diff options
author | Sven Tennie <sven.tennie@gmail.com> | 2021-04-03 19:35:34 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-09-23 15:59:38 -0400 |
commit | 29717ecb0711cd03796510fbe9b4bff58c7da870 (patch) | |
tree | 850a449ef01caeedf8fd8e9156e7eedcd5a028ce /compiler/GHC/Stg | |
parent | 6f7f59901c047882ba8c9ae8812264f86b12483a (diff) | |
download | haskell-29717ecb0711cd03796510fbe9b4bff58c7da870.tar.gz |
Use Info Table Provenances to decode cloned stack (#18163)
Emit an Info Table Provenance Entry (IPE) for every stack represeted info table
if -finfo-table-map is turned on.
To decode a cloned stack, lookupIPE() is used. It provides a mapping between
info tables and their source location.
Please see these notes for details:
- [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)]
- [Mapping Info Tables to Source Positions]
Metric Increase:
T12545
Diffstat (limited to 'compiler/GHC/Stg')
-rw-r--r-- | compiler/GHC/Stg/Debug.hs | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/compiler/GHC/Stg/Debug.hs b/compiler/GHC/Stg/Debug.hs index 77ef7910ec..bea6fe5c8e 100644 --- a/compiler/GHC/Stg/Debug.hs +++ b/compiler/GHC/Stg/Debug.hs @@ -33,7 +33,7 @@ data R = R { rDynFlags :: DynFlags, rModLocation :: ModLocation, rSpan :: Maybe type M a = ReaderT R (State InfoTableProvMap) a -withSpan :: (RealSrcSpan, String) -> M a -> M a +withSpan :: IpeSourceLocation -> M a -> M a withSpan (new_s, new_l) act = local maybe_replace act where maybe_replace r@R{ rModLocation = cur_mod, rSpan = Just (SpanWithLabel old_s _old_l) } @@ -171,16 +171,21 @@ to a position in the source. The prime example is being able to map a THUNK to a specific place in the source program, the mapping is usually quite precise because a fresh info table is created for each distinct THUNK. +The info table map is also used to generate stacktraces. +See Note [Stacktraces from Info Table Provenance Entries (IPE based stack unwinding)] +for details. + There are three parts to the implementation -1. In GHC.Stg.Debug, the SourceNote information is used in order to give a source location to -some specific closures. -2. In StgToCmm, the actually used info tables are recorded in an IORef, this -is important as it's hard to predict beforehand what code generation will do -and which ids will end up in the generated program. -3. During code generation, a mapping from the info table to the statically -determined location is emitted which can then be queried at runtime by -various tools. +1. In GHC.Stg.Debug, the SourceNote information is used in order to give a source location + to some specific closures. +2. In GHC.Driver.GenerateCgIPEStub, the actually used info tables are collected after the + Cmm pipeline. This is important as it's hard to predict beforehand what code generation + will do and which ids will end up in the generated program. Additionally, info tables of + return frames (used to create stacktraces) are generated in the Cmm pipeline and aren't + available before. +3. During code generation, a mapping from the info table to the statically determined location + is emitted which can then be queried at runtime by various tools. -- Giving Source Locations to Closures @@ -189,6 +194,8 @@ is collected in the `InfoTableProvMap` which provides a mapping from: 1. Data constructors to a list of where they are used. 2. `Name`s and where they originate from. +3. Stack represented info tables (return frames) to an approximated source location + of the call that pushed a contiunation on the stacks. During the CoreToStg phase, this map is populated whenever something is turned into a StgRhsClosure or an StgConApp. The current source position is recorded @@ -197,28 +204,27 @@ depending on the location indicated by the surrounding SourceNote. The functions which add information to the map are `recordStgIdPosition` and `numberDataCon`. -When the -fdistinct-constructor-tables` flag is turned on then every +When the `-fdistinct-constructor-tables` flag is turned on then every usage of a data constructor gets its own distinct info table. This is orchestrated in `collectExpr` where an incrementing number is used to distinguish each occurrence of a data constructor. --- StgToCmm +-- GenerateCgIPEStub + +The info tables which are actually used in the generated program are collected after +the Cmm pipeline. `initInfoTableProv` is used to create a CStub, that initializes the +map in C code. -The info tables which are actually used in the generated program are recorded during the -conversion from STG to Cmm. The used info tables are recorded in the `emitProc` function. -All the used info tables are recorded in the `cgs_used_info` field. This step -is necessary because when the information about names is collected in the previous -phase it's unpredictable about which names will end up needing info tables. If -you don't record which ones are actually used then you end up generating code -which references info tables which don't exist. +This step has to be done after the Cmm pipeline to make sure that all info tables are +really used and, even more importantly, return frame info tables are generated by the +pipeline. -- Code Generation The output of these two phases is combined together during code generation. -A C stub is generated which -creates the static map from info table pointer to the information about where that -info table was created from. This is created by `ipInitCode` in the same manner as a -C stub is generated for cost centres. +A C stub is generated which creates the static map from info table pointer to the +information about where that info table was created from. This is created by +`ipInitCode` in the same manner as a C stub is generated for cost centres. This information can be consumed in two ways. |