1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__
31 #define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__
32 
33 #include <string>
34 
35 #include "common/using_std_string.h"
36 #include "google_breakpad/common/breakpad_types.h"
37 
38 namespace google_breakpad {
39 
40 class CodeModule;
41 
42 struct StackFrame {
43   // Indicates how well the instruction pointer derived during
44   // stack walking is trusted. Since the stack walker can resort to
45   // stack scanning, it can wind up with dubious frames.
46   // In rough order of "trust metric".
47   enum FrameTrust {
48     FRAME_TRUST_NONE,      // Unknown
49     FRAME_TRUST_SCAN,      // Scanned the stack, found this
50     FRAME_TRUST_CFI_SCAN,  // Found while scanning stack using call frame info
51     FRAME_TRUST_FP,        // Derived from frame pointer
52     FRAME_TRUST_CFI,       // Derived from call frame info
53     FRAME_TRUST_PREWALKED, // Explicitly provided by some external stack walker.
54     FRAME_TRUST_CONTEXT    // Given as instruction pointer in a context
55   };
56 
StackFrameStackFrame57   StackFrame()
58       : instruction(),
59         module(NULL),
60         function_name(),
61         function_base(),
62         source_file_name(),
63         source_line(),
64         source_line_base(),
65         trust(FRAME_TRUST_NONE) {}
~StackFrameStackFrame66   virtual ~StackFrame() {}
67 
68   // Return a string describing how this stack frame was found
69   // by the stackwalker.
trust_descriptionStackFrame70   string trust_description() const {
71     switch (trust) {
72       case StackFrame::FRAME_TRUST_CONTEXT:
73         return "given as instruction pointer in context";
74       case StackFrame::FRAME_TRUST_PREWALKED:
75         return "recovered by external stack walker";
76       case StackFrame::FRAME_TRUST_CFI:
77         return "call frame info";
78       case StackFrame::FRAME_TRUST_CFI_SCAN:
79         return "call frame info with scanning";
80       case StackFrame::FRAME_TRUST_FP:
81         return "previous frame's frame pointer";
82       case StackFrame::FRAME_TRUST_SCAN:
83         return "stack scanning";
84       default:
85         return "unknown";
86     }
87   };
88 
89   // Return the actual return address, as saved on the stack or in a
90   // register. See the comments for 'instruction', below, for details.
ReturnAddressStackFrame91   virtual uint64_t ReturnAddress() const { return instruction; }
92 
93   // The program counter location as an absolute virtual address.
94   //
95   // - For the innermost called frame in a stack, this will be an exact
96   //   program counter or instruction pointer value.
97   //
98   // - For all other frames, this address is within the instruction that
99   //   caused execution to branch to this frame's callee (although it may
100   //   not point to the exact beginning of that instruction). This ensures
101   //   that, when we look up the source code location for this frame, we
102   //   get the source location of the call, not of the point at which
103   //   control will resume when the call returns, which may be on the next
104   //   line. (If the compiler knows the callee never returns, it may even
105   //   place the call instruction at the very end of the caller's machine
106   //   code, such that the "return address" (which will never be used)
107   //   immediately after the call instruction is in an entirely different
108   //   function, perhaps even from a different source file.)
109   //
110   // On some architectures, the return address as saved on the stack or in
111   // a register is fine for looking up the point of the call. On others, it
112   // requires adjustment. ReturnAddress returns the address as saved by the
113   // machine.
114   uint64_t instruction;
115 
116   // The module in which the instruction resides.
117   const CodeModule *module;
118 
119   // The function name, may be omitted if debug symbols are not available.
120   string function_name;
121 
122   // The start address of the function, may be omitted if debug symbols
123   // are not available.
124   uint64_t function_base;
125 
126   // The source file name, may be omitted if debug symbols are not available.
127   string source_file_name;
128 
129   // The (1-based) source line number, may be omitted if debug symbols are
130   // not available.
131   int source_line;
132 
133   // The start address of the source line, may be omitted if debug symbols
134   // are not available.
135   uint64_t source_line_base;
136 
137   // Amount of trust the stack walker has in the instruction pointer
138   // of this frame.
139   FrameTrust trust;
140 };
141 
142 }  // namespace google_breakpad
143 
144 #endif  // GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_H__
145