| Index: docs/stack_walking.md
|
| diff --git a/docs/stack_walking.md b/docs/stack_walking.md
|
| index c74f22d4949e38104dd903502e9b5b2f3f4fad00..a3b8cd45abc28575e918fa53d10dd8d5f767f83f 100644
|
| --- a/docs/stack_walking.md
|
| +++ b/docs/stack_walking.md
|
| @@ -8,47 +8,45 @@ traces from the information contained within a minidump file.
|
| ## Starting the Process
|
|
|
| Typically the stack walking process is initiated by instantiating the
|
| -[MinidumpProcessor]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/minidump_processor.cc)
|
| -class and calling the [MinidumpProcessor::Process]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/minidump_processor.cc#61)
|
| +[MinidumpProcessor](/src/processor/minidump_processor.cc)
|
| +class and calling the
|
| +[MinidumpProcessor::Process](/src/processor/minidump_processor.cc#61)
|
| method, providing it a minidump file to process. To produce a useful stack
|
| trace, the MinidumpProcessor requires two other objects which are passed in its
|
| -constructor: a [SymbolSupplier]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/symbol_supplier.h)
|
| -and a [SourceLineResolverInterface]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/source_line_resolver_interface.h).
|
| +constructor: a
|
| +[SymbolSupplier](/src/google_breakpad/processor/symbol_supplier.h)
|
| +and a
|
| +[SourceLineResolverInterface](/src/google_breakpad/processor/source_line_resolver_interface.h).
|
| The SymbolSupplier object is responsible for locating and providing SymbolFiles
|
| that match modules from the minidump. The SourceLineResolverInterface is
|
| -responsible for loading the symbol files and using the information contained
|
| +responsible for loading the [symbol files](symbol_files.md) and using the information contained
|
| within to provide function and source information for stack frames, as well as
|
| information on how to unwind from a stack frame to its caller. More detail will
|
| be provided on these interactions later.
|
|
|
| A number of data streams are extracted from the minidump to begin stack walking:
|
| -the list of threads from the process ([MinidumpThreadList]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/minidump.h#335)),
|
| -the list of modules loaded in the process ([MinidumpModuleList]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/minidump.h#501)),
|
| +the list of threads from the process
|
| +([MinidumpThreadList](/src/google_breakpad/processor/minidump.h#335)),
|
| +the list of modules loaded in the process
|
| +([MinidumpModuleList](/src/google_breakpad/processor/minidump.h#501)),
|
| and information about the exception that caused the process to crash
|
| -([MinidumpException]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/minidump.h#615)).
|
| +([MinidumpException](/src/google_breakpad/processor/minidump.h#615)).
|
|
|
| ## Enumerating Threads
|
|
|
| -For each thread in the thread list ([MinidumpThread]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/minidump.h#299)),
|
| -the thread memory containing the stack for the thread ([MinidumpMemoryRegion]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/minidump.h#236))
|
| +For each thread in the thread list
|
| +([MinidumpThread](/src/google_breakpad/processor/minidump.h#299)),
|
| +the thread memory containing the stack for the thread
|
| +([MinidumpMemoryRegion](/src/google_breakpad/processor/minidump.h#236))
|
| and the CPU context representing the CPU state of the thread at the time the
|
| -dump was written ([MinidumpContext]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/minidump.h#171))
|
| +dump was written
|
| +([MinidumpContext](/src/google_breakpad/processor/minidump.h#171))
|
| are extracted from the minidump. If the thread being processed is the thread
|
| that produced the exception then a CPU context is obtained from the
|
| MinidumpException object instead, which represents the CPU state of the thread
|
| at the point of the exception. A stack walker is then instantiated by calling
|
| -the [Stackwalker::StackwalkerForCPU]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/stackwalker.h#77)
|
| +the
|
| +[Stackwalker::StackwalkerForCPU](/src/google_breakpad/processor/stackwalker.h#77)
|
| method and passing it the CPU context, the thread memory, the module list, as
|
| well as the SymbolSupplier and SourceLineResolverInterface. This method selects
|
| the specific !Stackwalker subclass based on the CPU architecture of the provided
|
| @@ -57,8 +55,7 @@ CPU context and returns an instance of that subclass.
|
| ## Walking a thread's stack
|
|
|
| Once a !Stackwalker instance has been obtained, the processor calls the
|
| -[Stackwalker::Walk]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/source_line_resolver_interface.h)
|
| +[Stackwalker::Walk](/src/google_breakpad/processor/source_line_resolver_interface.h)
|
| method to obtain a list of frames representing the stack of this thread. The
|
| !Stackwalker starts by calling the GetContextFrame method which returns a
|
| StackFrame representing the top of the stack, with CPU state provided by the
|
| @@ -69,71 +66,68 @@ for each frame in turn:
|
|
|
| The address of the instruction pointer of the current frame is used to determine
|
| which module contains the current frame by calling the module list's
|
| -[GetModuleForAddress]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/code_modules.h#56)
|
| +[GetModuleForAddress](/src/google_breakpad/processor/code_modules.h#56)
|
| method.
|
|
|
| ### Locating Symbols
|
|
|
| If a module is located, the SymbolSupplier is asked to locate symbols
|
| -corresponding to the module by calling its [GetCStringSymbolData]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/symbol_supplier.h#87)
|
| +corresponding to the module by calling its
|
| +[GetCStringSymbolData](/src/google_breakpad/processor/symbol_supplier.h#87)
|
| method. Typically this is implemented by using the module's debug filename (the
|
| PDB filename for Windows dumps) and debug identifier (a GUID plus one extra
|
| -digit) as a lookup key. The [SimpleSymbolSupplier]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/simple_symbol_supplier.cc)
|
| +digit) as a lookup key. The
|
| +[SimpleSymbolSupplier](/src/processor/simple_symbol_supplier.cc)
|
| class simply uses these as parts of a file path to locate a flat file on disk.
|
|
|
| ### Loading Symbols
|
|
|
| -If a symbol file is located, the SourceLineResolverInterface is then asked to
|
| -load the symbol file by calling its [LoadModuleUsingMemoryBuffer]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/source_line_resolver_interface.h#71)
|
| -method. The [BasicSourceLineResolver]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/basic_source_line_resolver.cc)
|
| +If a [symbol file](symbol_files.md) is located, the SourceLineResolverInterface is then asked to
|
| +load the [symbol file](symbol_files.md) by calling its
|
| +[LoadModuleUsingMemoryBuffer](/src/google_breakpad/processor/source_line_resolver_interface.h#71)
|
| +method. The
|
| +[BasicSourceLineResolver](/src/processor/basic_source_line_resolver.cc)
|
| implementation parses the text-format [symbol file](symbol_files.md) into
|
| in-memory data structures to make lookups by address of function names, source
|
| line information, and unwind information easy.
|
|
|
| ### Getting source line information
|
|
|
| -If a symbol file has been successfully loaded, the SourceLineResolverInterface's
|
| -[FillSourceLineInfo]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/source_line_resolver_interface.h#89)
|
| +If a [symbol file](symbol_files.md) has been successfully loaded, the SourceLineResolverInterface's
|
| +[FillSourceLineInfo](/src/google_breakpad/processor/source_line_resolver_interface.h#89)
|
| method is called to provide a function name and source line information for the
|
| current frame. This is done by subtracting the base address of the module
|
| containing the current frame from the instruction pointer of the current frame
|
| to obtain a relative virtual address (RVA), which is a code offset relative to
|
| the start of the module. This RVA is then used as a lookup into a table of
|
| -functions ([FUNC lines](SymbolFiles#FUNC_records.md) from the symbol file), each
|
| +functions ([FUNC lines](symbol_files.md#records-3) from the [symbol file](symbol_files.md)), each
|
| of which has an associated address range (function start address, function
|
| size). If a function is found whose address range contains the RVA, then its
|
| name is used. The RVA is then used as a lookup into a table of source lines
|
| -([line records](SymbolFiles#Line_records.md) from the symbol file), each of
|
| +([line records](symbol_files.md#Line-records) from the [symbol file](symbol_files.md)), each of
|
| which also has an associated address range. If a match is found it will provide
|
| the file name and source line associated with the current frame. If no match was
|
| found in the function table, another table of publicly exported symbols may be
|
| -consulted ([PUBLIC lines](SymbolFiles#PUBLIC_records.md) from the symbol file).
|
| +consulted ([PUBLIC lines](symbol_files.md#records-4) from the [symbol file](symbol_files.md)).
|
| Public symbols contain only a start address, so the lookup simply looks for the
|
| nearest symbol that is less than the provided RVA.
|
|
|
| ### Finding the caller frame
|
|
|
| -To find the next frame in the stack, the !Stackwalker calls its [GetCallerFrame]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/stackwalker.h#186)
|
| +To find the next frame in the stack, the !Stackwalker calls its
|
| +[GetCallerFrame](/src/google_breakpad/processor/stackwalker.h#186)
|
| method, passing in the current frame. Each !Stackwalker subclass implements
|
| GetCallerFrame differently, but there are common patterns.
|
|
|
| Typically the first step is to query the SourceLineResolverInterface for the
|
| presence of detailed unwind information. This is done using its
|
| -[FindWindowsFrameInfo]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/source_line_resolver_interface.h#96)
|
| -and [FindCFIFrameInfo]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/source_line_resolver_interface.h#102)
|
| +[FindWindowsFrameInfo](/src/google_breakpad/processor/source_line_resolver_interface.h#96)
|
| +and
|
| +[FindCFIFrameInfo](/src/google_breakpad/processor/source_line_resolver_interface.h#102)
|
| methods. These methods look for Windows unwind info extracted from a PDB file
|
| -([STACK WIN](SymbolFiles#STACK_WIN_records.md) lines from the symbol file), or
|
| -DWARF CFI extracted from a binary ([STACK CFI](SymbolFiles#STACK_CFI_records.md)
|
| -lines from the symbol file) respectively. The information covers address ranges,
|
| +([STACK WIN](symbol_files.md#records-5) lines from the [symbol file](symbol_files.md)), or
|
| +DWARF CFI extracted from a binary ([STACK CFI](symbol_files.md#records-6)
|
| +lines from the [symbol file](symbol_files.md)) respectively. The information covers address ranges,
|
| so the RVA of the current frame is used for lookup as with function and source
|
| line information.
|
|
|
| @@ -148,11 +142,11 @@ to produce the caller frame.
|
|
|
| If no caller frame was found by any other method most !Stackwalker
|
| implementations resort to stack scanning by looking at each word on the stack
|
| -down to a fixed depth (implemented in the [Stackwalker::ScanForReturnAddress]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/stackwalker.h#131)
|
| +down to a fixed depth (implemented in the
|
| +[Stackwalker::ScanForReturnAddress](/src/google_breakpad/processor/stackwalker.h#131)
|
| method) and using a heuristic to attempt to find a reasonable return address
|
| -(implemented in the [Stackwalker::InstructionAddressSeemsValid]
|
| -(http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpad/processor/stackwalker.h#111)
|
| +(implemented in the
|
| +[Stackwalker::InstructionAddressSeemsValid](/src/google_breakpad/processor/stackwalker.h#111)
|
| method).
|
|
|
| If no caller frame is found or the caller frame seems invalid, stack walking
|
|
|