| OLD | NEW |
| 1 # Introduction | 1 # Introduction |
| 2 | 2 |
| 3 This page aims to provide a detailed description of how Breakpad produces stack | 3 This page aims to provide a detailed description of how Breakpad produces stack |
| 4 traces from the information contained within a minidump file. | 4 traces from the information contained within a minidump file. |
| 5 | 5 |
| 6 # Details | 6 # Details |
| 7 | 7 |
| 8 ## Starting the Process | 8 ## Starting the Process |
| 9 | 9 |
| 10 Typically the stack walking process is initiated by instantiating the | 10 Typically the stack walking process is initiated by instantiating the |
| 11 [MinidumpProcessor] | 11 [MinidumpProcessor](/src/processor/minidump_processor.cc) |
| 12 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/mini
dump_processor.cc) | 12 class and calling the |
| 13 class and calling the [MinidumpProcessor::Process] | 13 [MinidumpProcessor::Process](/src/processor/minidump_processor.cc#61) |
| 14 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/mini
dump_processor.cc#61) | |
| 15 method, providing it a minidump file to process. To produce a useful stack | 14 method, providing it a minidump file to process. To produce a useful stack |
| 16 trace, the MinidumpProcessor requires two other objects which are passed in its | 15 trace, the MinidumpProcessor requires two other objects which are passed in its |
| 17 constructor: a [SymbolSupplier] | 16 constructor: a |
| 18 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/symbol_supplier.h) | 17 [SymbolSupplier](/src/google_breakpad/processor/symbol_supplier.h) |
| 19 and a [SourceLineResolverInterface] | 18 and a |
| 20 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/source_line_resolver_interface.h). | 19 [SourceLineResolverInterface](/src/google_breakpad/processor/source_line_resolve
r_interface.h). |
| 21 The SymbolSupplier object is responsible for locating and providing SymbolFiles | 20 The SymbolSupplier object is responsible for locating and providing SymbolFiles |
| 22 that match modules from the minidump. The SourceLineResolverInterface is | 21 that match modules from the minidump. The SourceLineResolverInterface is |
| 23 responsible for loading the symbol files and using the information contained | 22 responsible for loading the [symbol files](symbol_files.md) and using the inform
ation contained |
| 24 within to provide function and source information for stack frames, as well as | 23 within to provide function and source information for stack frames, as well as |
| 25 information on how to unwind from a stack frame to its caller. More detail will | 24 information on how to unwind from a stack frame to its caller. More detail will |
| 26 be provided on these interactions later. | 25 be provided on these interactions later. |
| 27 | 26 |
| 28 A number of data streams are extracted from the minidump to begin stack walking: | 27 A number of data streams are extracted from the minidump to begin stack walking: |
| 29 the list of threads from the process ([MinidumpThreadList] | 28 the list of threads from the process |
| 30 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/minidump.h#335)), | 29 ([MinidumpThreadList](/src/google_breakpad/processor/minidump.h#335)), |
| 31 the list of modules loaded in the process ([MinidumpModuleList] | 30 the list of modules loaded in the process |
| 32 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/minidump.h#501)), | 31 ([MinidumpModuleList](/src/google_breakpad/processor/minidump.h#501)), |
| 33 and information about the exception that caused the process to crash | 32 and information about the exception that caused the process to crash |
| 34 ([MinidumpException] | 33 ([MinidumpException](/src/google_breakpad/processor/minidump.h#615)). |
| 35 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/minidump.h#615)). | |
| 36 | 34 |
| 37 ## Enumerating Threads | 35 ## Enumerating Threads |
| 38 | 36 |
| 39 For each thread in the thread list ([MinidumpThread] | 37 For each thread in the thread list |
| 40 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/minidump.h#299)), | 38 ([MinidumpThread](/src/google_breakpad/processor/minidump.h#299)), |
| 41 the thread memory containing the stack for the thread ([MinidumpMemoryRegion] | 39 the thread memory containing the stack for the thread |
| 42 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/minidump.h#236)) | 40 ([MinidumpMemoryRegion](/src/google_breakpad/processor/minidump.h#236)) |
| 43 and the CPU context representing the CPU state of the thread at the time the | 41 and the CPU context representing the CPU state of the thread at the time the |
| 44 dump was written ([MinidumpContext] | 42 dump was written |
| 45 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/minidump.h#171)) | 43 ([MinidumpContext](/src/google_breakpad/processor/minidump.h#171)) |
| 46 are extracted from the minidump. If the thread being processed is the thread | 44 are extracted from the minidump. If the thread being processed is the thread |
| 47 that produced the exception then a CPU context is obtained from the | 45 that produced the exception then a CPU context is obtained from the |
| 48 MinidumpException object instead, which represents the CPU state of the thread | 46 MinidumpException object instead, which represents the CPU state of the thread |
| 49 at the point of the exception. A stack walker is then instantiated by calling | 47 at the point of the exception. A stack walker is then instantiated by calling |
| 50 the [Stackwalker::StackwalkerForCPU] | 48 the |
| 51 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/stackwalker.h#77) | 49 [Stackwalker::StackwalkerForCPU](/src/google_breakpad/processor/stackwalker.h#77
) |
| 52 method and passing it the CPU context, the thread memory, the module list, as | 50 method and passing it the CPU context, the thread memory, the module list, as |
| 53 well as the SymbolSupplier and SourceLineResolverInterface. This method selects | 51 well as the SymbolSupplier and SourceLineResolverInterface. This method selects |
| 54 the specific !Stackwalker subclass based on the CPU architecture of the provided | 52 the specific !Stackwalker subclass based on the CPU architecture of the provided |
| 55 CPU context and returns an instance of that subclass. | 53 CPU context and returns an instance of that subclass. |
| 56 | 54 |
| 57 ## Walking a thread's stack | 55 ## Walking a thread's stack |
| 58 | 56 |
| 59 Once a !Stackwalker instance has been obtained, the processor calls the | 57 Once a !Stackwalker instance has been obtained, the processor calls the |
| 60 [Stackwalker::Walk] | 58 [Stackwalker::Walk](/src/google_breakpad/processor/source_line_resolver_interfac
e.h) |
| 61 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/source_line_resolver_interface.h) | |
| 62 method to obtain a list of frames representing the stack of this thread. The | 59 method to obtain a list of frames representing the stack of this thread. The |
| 63 !Stackwalker starts by calling the GetContextFrame method which returns a | 60 !Stackwalker starts by calling the GetContextFrame method which returns a |
| 64 StackFrame representing the top of the stack, with CPU state provided by the | 61 StackFrame representing the top of the stack, with CPU state provided by the |
| 65 initial CPU context. From there, the stack walker repeats the following steps | 62 initial CPU context. From there, the stack walker repeats the following steps |
| 66 for each frame in turn: | 63 for each frame in turn: |
| 67 | 64 |
| 68 ### Finding the Module | 65 ### Finding the Module |
| 69 | 66 |
| 70 The address of the instruction pointer of the current frame is used to determine | 67 The address of the instruction pointer of the current frame is used to determine |
| 71 which module contains the current frame by calling the module list's | 68 which module contains the current frame by calling the module list's |
| 72 [GetModuleForAddress] | 69 [GetModuleForAddress](/src/google_breakpad/processor/code_modules.h#56) |
| 73 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/code_modules.h#56) | |
| 74 method. | 70 method. |
| 75 | 71 |
| 76 ### Locating Symbols | 72 ### Locating Symbols |
| 77 | 73 |
| 78 If a module is located, the SymbolSupplier is asked to locate symbols | 74 If a module is located, the SymbolSupplier is asked to locate symbols |
| 79 corresponding to the module by calling its [GetCStringSymbolData] | 75 corresponding to the module by calling its |
| 80 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/symbol_supplier.h#87) | 76 [GetCStringSymbolData](/src/google_breakpad/processor/symbol_supplier.h#87) |
| 81 method. Typically this is implemented by using the module's debug filename (the | 77 method. Typically this is implemented by using the module's debug filename (the |
| 82 PDB filename for Windows dumps) and debug identifier (a GUID plus one extra | 78 PDB filename for Windows dumps) and debug identifier (a GUID plus one extra |
| 83 digit) as a lookup key. The [SimpleSymbolSupplier] | 79 digit) as a lookup key. The |
| 84 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/simp
le_symbol_supplier.cc) | 80 [SimpleSymbolSupplier](/src/processor/simple_symbol_supplier.cc) |
| 85 class simply uses these as parts of a file path to locate a flat file on disk. | 81 class simply uses these as parts of a file path to locate a flat file on disk. |
| 86 | 82 |
| 87 ### Loading Symbols | 83 ### Loading Symbols |
| 88 | 84 |
| 89 If a symbol file is located, the SourceLineResolverInterface is then asked to | 85 If a [symbol file](symbol_files.md) is located, the SourceLineResolverInterface
is then asked to |
| 90 load the symbol file by calling its [LoadModuleUsingMemoryBuffer] | 86 load the [symbol file](symbol_files.md) by calling its |
| 91 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/source_line_resolver_interface.h#71) | 87 [LoadModuleUsingMemoryBuffer](/src/google_breakpad/processor/source_line_resolve
r_interface.h#71) |
| 92 method. The [BasicSourceLineResolver] | 88 method. The |
| 93 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/basi
c_source_line_resolver.cc) | 89 [BasicSourceLineResolver](/src/processor/basic_source_line_resolver.cc) |
| 94 implementation parses the text-format [symbol file](symbol_files.md) into | 90 implementation parses the text-format [symbol file](symbol_files.md) into |
| 95 in-memory data structures to make lookups by address of function names, source | 91 in-memory data structures to make lookups by address of function names, source |
| 96 line information, and unwind information easy. | 92 line information, and unwind information easy. |
| 97 | 93 |
| 98 ### Getting source line information | 94 ### Getting source line information |
| 99 | 95 |
| 100 If a symbol file has been successfully loaded, the SourceLineResolverInterface's | 96 If a [symbol file](symbol_files.md) has been successfully loaded, the SourceLine
ResolverInterface's |
| 101 [FillSourceLineInfo] | 97 [FillSourceLineInfo](/src/google_breakpad/processor/source_line_resolver_interfa
ce.h#89) |
| 102 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/source_line_resolver_interface.h#89) | |
| 103 method is called to provide a function name and source line information for the | 98 method is called to provide a function name and source line information for the |
| 104 current frame. This is done by subtracting the base address of the module | 99 current frame. This is done by subtracting the base address of the module |
| 105 containing the current frame from the instruction pointer of the current frame | 100 containing the current frame from the instruction pointer of the current frame |
| 106 to obtain a relative virtual address (RVA), which is a code offset relative to | 101 to obtain a relative virtual address (RVA), which is a code offset relative to |
| 107 the start of the module. This RVA is then used as a lookup into a table of | 102 the start of the module. This RVA is then used as a lookup into a table of |
| 108 functions ([FUNC lines](SymbolFiles#FUNC_records.md) from the symbol file), each | 103 functions ([FUNC lines](symbol_files.md#records-3) from the [symbol file](symbol
_files.md)), each |
| 109 of which has an associated address range (function start address, function | 104 of which has an associated address range (function start address, function |
| 110 size). If a function is found whose address range contains the RVA, then its | 105 size). If a function is found whose address range contains the RVA, then its |
| 111 name is used. The RVA is then used as a lookup into a table of source lines | 106 name is used. The RVA is then used as a lookup into a table of source lines |
| 112 ([line records](SymbolFiles#Line_records.md) from the symbol file), each of | 107 ([line records](symbol_files.md#Line-records) from the [symbol file](symbol_file
s.md)), each of |
| 113 which also has an associated address range. If a match is found it will provide | 108 which also has an associated address range. If a match is found it will provide |
| 114 the file name and source line associated with the current frame. If no match was | 109 the file name and source line associated with the current frame. If no match was |
| 115 found in the function table, another table of publicly exported symbols may be | 110 found in the function table, another table of publicly exported symbols may be |
| 116 consulted ([PUBLIC lines](SymbolFiles#PUBLIC_records.md) from the symbol file). | 111 consulted ([PUBLIC lines](symbol_files.md#records-4) from the [symbol file](symb
ol_files.md)). |
| 117 Public symbols contain only a start address, so the lookup simply looks for the | 112 Public symbols contain only a start address, so the lookup simply looks for the |
| 118 nearest symbol that is less than the provided RVA. | 113 nearest symbol that is less than the provided RVA. |
| 119 | 114 |
| 120 ### Finding the caller frame | 115 ### Finding the caller frame |
| 121 | 116 |
| 122 To find the next frame in the stack, the !Stackwalker calls its [GetCallerFrame] | 117 To find the next frame in the stack, the !Stackwalker calls its |
| 123 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/stackwalker.h#186) | 118 [GetCallerFrame](/src/google_breakpad/processor/stackwalker.h#186) |
| 124 method, passing in the current frame. Each !Stackwalker subclass implements | 119 method, passing in the current frame. Each !Stackwalker subclass implements |
| 125 GetCallerFrame differently, but there are common patterns. | 120 GetCallerFrame differently, but there are common patterns. |
| 126 | 121 |
| 127 Typically the first step is to query the SourceLineResolverInterface for the | 122 Typically the first step is to query the SourceLineResolverInterface for the |
| 128 presence of detailed unwind information. This is done using its | 123 presence of detailed unwind information. This is done using its |
| 129 [FindWindowsFrameInfo] | 124 [FindWindowsFrameInfo](/src/google_breakpad/processor/source_line_resolver_inter
face.h#96) |
| 130 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/source_line_resolver_interface.h#96) | 125 and |
| 131 and [FindCFIFrameInfo] | 126 [FindCFIFrameInfo](/src/google_breakpad/processor/source_line_resolver_interface
.h#102) |
| 132 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/source_line_resolver_interface.h#102) | |
| 133 methods. These methods look for Windows unwind info extracted from a PDB file | 127 methods. These methods look for Windows unwind info extracted from a PDB file |
| 134 ([STACK WIN](SymbolFiles#STACK_WIN_records.md) lines from the symbol file), or | 128 ([STACK WIN](symbol_files.md#records-5) lines from the [symbol file](symbol_file
s.md)), or |
| 135 DWARF CFI extracted from a binary ([STACK CFI](SymbolFiles#STACK_CFI_records.md) | 129 DWARF CFI extracted from a binary ([STACK CFI](symbol_files.md#records-6) |
| 136 lines from the symbol file) respectively. The information covers address ranges, | 130 lines from the [symbol file](symbol_files.md)) respectively. The information cov
ers address ranges, |
| 137 so the RVA of the current frame is used for lookup as with function and source | 131 so the RVA of the current frame is used for lookup as with function and source |
| 138 line information. | 132 line information. |
| 139 | 133 |
| 140 If unwind info is found it provides a set of rules to recover the register state | 134 If unwind info is found it provides a set of rules to recover the register state |
| 141 of the caller frame given the current register state as well as the thread's | 135 of the caller frame given the current register state as well as the thread's |
| 142 stack memory. The rules are evaluated to produce the caller frame. | 136 stack memory. The rules are evaluated to produce the caller frame. |
| 143 | 137 |
| 144 If unwind info is not found then the !Stackwalker may resort to other methods. | 138 If unwind info is not found then the !Stackwalker may resort to other methods. |
| 145 Typically on architectures which specify a frame pointer unwinding by | 139 Typically on architectures which specify a frame pointer unwinding by |
| 146 dereferencing the frame pointer is tried next. If that is successful it is used | 140 dereferencing the frame pointer is tried next. If that is successful it is used |
| 147 to produce the caller frame. | 141 to produce the caller frame. |
| 148 | 142 |
| 149 If no caller frame was found by any other method most !Stackwalker | 143 If no caller frame was found by any other method most !Stackwalker |
| 150 implementations resort to stack scanning by looking at each word on the stack | 144 implementations resort to stack scanning by looking at each word on the stack |
| 151 down to a fixed depth (implemented in the [Stackwalker::ScanForReturnAddress] | 145 down to a fixed depth (implemented in the |
| 152 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/stackwalker.h#131) | 146 [Stackwalker::ScanForReturnAddress](/src/google_breakpad/processor/stackwalker.h
#131) |
| 153 method) and using a heuristic to attempt to find a reasonable return address | 147 method) and using a heuristic to attempt to find a reasonable return address |
| 154 (implemented in the [Stackwalker::InstructionAddressSeemsValid] | 148 (implemented in the |
| 155 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa
d/processor/stackwalker.h#111) | 149 [Stackwalker::InstructionAddressSeemsValid](/src/google_breakpad/processor/stack
walker.h#111) |
| 156 method). | 150 method). |
| 157 | 151 |
| 158 If no caller frame is found or the caller frame seems invalid, stack walking | 152 If no caller frame is found or the caller frame seems invalid, stack walking |
| 159 stops. If a caller frame was found then these steps repeat using the new frame | 153 stops. If a caller frame was found then these steps repeat using the new frame |
| 160 as the current frame. | 154 as the current frame. |
| OLD | NEW |