Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: docs/stack_walking.md

Issue 1357773004: [Docs] add markdown docs (converted from Wiki) (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: whoops' Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « docs/processor_design.md ('k') | docs/symbol_files.md » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Introduction
2
3 This page aims to provide a detailed description of how Breakpad produces stack
4 traces from the information contained within a minidump file.
5
6 # Details
7
8 ## Starting the Process
9
10 Typically the stack walking process is initiated by instantiating the
11 [MinidumpProcessor]
12 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/mini dump_processor.cc)
13 class and calling the [MinidumpProcessor::Process]
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
16 trace, the MinidumpProcessor requires two other objects which are passed in its
17 constructor: a [SymbolSupplier]
18 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/symbol_supplier.h)
19 and a [SourceLineResolverInterface]
20 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/source_line_resolver_interface.h).
21 The SymbolSupplier object is responsible for locating and providing SymbolFiles
22 that match modules from the minidump. The SourceLineResolverInterface is
23 responsible for loading the symbol files and using the information contained
24 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
26 be provided on these interactions later.
27
28 A number of data streams are extracted from the minidump to begin stack walking:
29 the list of threads from the process ([MinidumpThreadList]
30 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/minidump.h#335)),
31 the list of modules loaded in the process ([MinidumpModuleList]
32 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/minidump.h#501)),
33 and information about the exception that caused the process to crash
34 ([MinidumpException]
35 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/minidump.h#615)).
36
37 ## Enumerating Threads
38
39 For each thread in the thread list ([MinidumpThread]
40 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/minidump.h#299)),
41 the thread memory containing the stack for the thread ([MinidumpMemoryRegion]
42 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/minidump.h#236))
43 and the CPU context representing the CPU state of the thread at the time the
44 dump was written ([MinidumpContext]
45 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/minidump.h#171))
46 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
48 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
50 the [Stackwalker::StackwalkerForCPU]
51 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/stackwalker.h#77)
52 method and passing it the CPU context, the thread memory, the module list, as
53 well as the SymbolSupplier and SourceLineResolverInterface. This method selects
54 the specific !Stackwalker subclass based on the CPU architecture of the provided
55 CPU context and returns an instance of that subclass.
56
57 ## Walking a thread's stack
58
59 Once a !Stackwalker instance has been obtained, the processor calls the
60 [Stackwalker::Walk]
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
63 !Stackwalker starts by calling the GetContextFrame method which returns a
64 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
66 for each frame in turn:
67
68 ### Finding the Module
69
70 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
72 [GetModuleForAddress]
73 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/code_modules.h#56)
74 method.
75
76 ### Locating Symbols
77
78 If a module is located, the SymbolSupplier is asked to locate symbols
79 corresponding to the module by calling its [GetCStringSymbolData]
80 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/symbol_supplier.h#87)
81 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
83 digit) as a lookup key. The [SimpleSymbolSupplier]
84 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/simp le_symbol_supplier.cc)
85 class simply uses these as parts of a file path to locate a flat file on disk.
86
87 ### Loading Symbols
88
89 If a symbol file is located, the SourceLineResolverInterface is then asked to
90 load the symbol file by calling its [LoadModuleUsingMemoryBuffer]
91 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/source_line_resolver_interface.h#71)
92 method. The [BasicSourceLineResolver]
93 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/processor/basi c_source_line_resolver.cc)
94 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
96 line information, and unwind information easy.
97
98 ### Getting source line information
99
100 If a symbol file has been successfully loaded, the SourceLineResolverInterface's
101 [FillSourceLineInfo]
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
104 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
106 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
108 functions ([FUNC lines](SymbolFiles#FUNC_records.md) from the symbol file), each
109 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
111 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
113 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
115 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).
117 Public symbols contain only a start address, so the lookup simply looks for the
118 nearest symbol that is less than the provided RVA.
119
120 ### Finding the caller frame
121
122 To find the next frame in the stack, the !Stackwalker calls its [GetCallerFrame]
123 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/stackwalker.h#186)
124 method, passing in the current frame. Each !Stackwalker subclass implements
125 GetCallerFrame differently, but there are common patterns.
126
127 Typically the first step is to query the SourceLineResolverInterface for the
128 presence of detailed unwind information. This is done using its
129 [FindWindowsFrameInfo]
130 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/source_line_resolver_interface.h#96)
131 and [FindCFIFrameInfo]
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
134 ([STACK WIN](SymbolFiles#STACK_WIN_records.md) lines from the symbol file), or
135 DWARF CFI extracted from a binary ([STACK CFI](SymbolFiles#STACK_CFI_records.md)
136 lines from the symbol file) respectively. The information covers address ranges,
137 so the RVA of the current frame is used for lookup as with function and source
138 line information.
139
140 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
142 stack memory. The rules are evaluated to produce the caller frame.
143
144 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
146 dereferencing the frame pointer is tried next. If that is successful it is used
147 to produce the caller frame.
148
149 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
151 down to a fixed depth (implemented in the [Stackwalker::ScanForReturnAddress]
152 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/stackwalker.h#131)
153 method) and using a heuristic to attempt to find a reasonable return address
154 (implemented in the [Stackwalker::InstructionAddressSeemsValid]
155 (http://code.google.com/p/google-breakpad/source/browse/trunk/src/google_breakpa d/processor/stackwalker.h#111)
156 method).
157
158 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
160 as the current frame.
OLDNEW
« no previous file with comments | « docs/processor_design.md ('k') | docs/symbol_files.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698