/thirdparty/breakpad/google_breakpad/processor/stackwalker.h

http://github.com/tomahawk-player/tomahawk · C Header · 203 lines · 76 code · 31 blank · 96 comment · 4 complexity · 076bf1548b8e3161bc75a6cbc0d9e8c0 MD5 · raw file

  1. // Copyright (c) 2010 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. // stackwalker.h: Generic stackwalker.
  30. //
  31. // The Stackwalker class is an abstract base class providing common generic
  32. // methods that apply to stacks from all systems. Specific implementations
  33. // will extend this class by providing GetContextFrame and GetCallerFrame
  34. // methods to fill in system-specific data in a StackFrame structure.
  35. // Stackwalker assembles these StackFrame strucutres into a CallStack.
  36. //
  37. // Author: Mark Mentovai
  38. #ifndef GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
  39. #define GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
  40. #include <set>
  41. #include <string>
  42. #include "google_breakpad/common/breakpad_types.h"
  43. #include "google_breakpad/processor/code_modules.h"
  44. #include "google_breakpad/processor/memory_region.h"
  45. namespace google_breakpad {
  46. class CallStack;
  47. class MinidumpContext;
  48. class SourceLineResolverInterface;
  49. struct StackFrame;
  50. class SymbolSupplier;
  51. struct SystemInfo;
  52. using std::set;
  53. class Stackwalker {
  54. public:
  55. virtual ~Stackwalker() {}
  56. // Populates the given CallStack by calling GetContextFrame and
  57. // GetCallerFrame. The frames are further processed to fill all available
  58. // data. Returns true if the stackwalk completed, or false if it was
  59. // interrupted by SymbolSupplier::GetSymbolFile().
  60. bool Walk(CallStack *stack);
  61. // Returns a new concrete subclass suitable for the CPU that a stack was
  62. // generated on, according to the CPU type indicated by the context
  63. // argument. If no suitable concrete subclass exists, returns NULL.
  64. static Stackwalker* StackwalkerForCPU(const SystemInfo *system_info,
  65. MinidumpContext *context,
  66. MemoryRegion *memory,
  67. const CodeModules *modules,
  68. SymbolSupplier *supplier,
  69. SourceLineResolverInterface *resolver);
  70. static void set_max_frames(u_int32_t max_frames) { max_frames_ = max_frames; }
  71. static u_int32_t max_frames() { return max_frames_; }
  72. protected:
  73. // system_info identifies the operating system, NULL or empty if unknown.
  74. // memory identifies a MemoryRegion that provides the stack memory
  75. // for the stack to walk. modules, if non-NULL, is a CodeModules
  76. // object that is used to look up which code module each stack frame is
  77. // associated with. supplier is an optional caller-supplied SymbolSupplier
  78. // implementation. If supplier is NULL, source line info will not be
  79. // resolved. resolver is an instance of SourceLineResolverInterface
  80. // (see source_line_resolver_interface.h and basic_source_line_resolver.h).
  81. // If resolver is NULL, source line info will not be resolved.
  82. Stackwalker(const SystemInfo *system_info,
  83. MemoryRegion *memory,
  84. const CodeModules *modules,
  85. SymbolSupplier *supplier,
  86. SourceLineResolverInterface *resolver);
  87. // This can be used to filter out potential return addresses when
  88. // the stack walker resorts to stack scanning.
  89. // Returns true if any of:
  90. // * This address is within a loaded module, but we don't have symbols
  91. // for that module.
  92. // * This address is within a loaded module for which we have symbols,
  93. // and falls inside a function in that module.
  94. // Returns false otherwise.
  95. bool InstructionAddressSeemsValid(u_int64_t address);
  96. template<typename InstructionType>
  97. bool ScanForReturnAddress(InstructionType location_start,
  98. InstructionType *location_found,
  99. InstructionType *ip_found) {
  100. const int kRASearchWords = 30;
  101. return ScanForReturnAddress(location_start, location_found, ip_found,
  102. kRASearchWords);
  103. }
  104. // Scan the stack starting at location_start, looking for an address
  105. // that looks like a valid instruction pointer. Addresses must
  106. // 1) be contained in the current stack memory
  107. // 2) pass the checks in InstructionAddressSeemsValid
  108. //
  109. // Returns true if a valid-looking instruction pointer was found.
  110. // When returning true, sets location_found to the address at which
  111. // the value was found, and ip_found to the value contained at that
  112. // location in memory.
  113. template<typename InstructionType>
  114. bool ScanForReturnAddress(InstructionType location_start,
  115. InstructionType *location_found,
  116. InstructionType *ip_found,
  117. int searchwords) {
  118. for (InstructionType location = location_start;
  119. location <= location_start + searchwords * sizeof(InstructionType);
  120. location += sizeof(InstructionType)) {
  121. InstructionType ip;
  122. if (!memory_->GetMemoryAtAddress(location, &ip))
  123. break;
  124. if (modules_ && modules_->GetModuleForAddress(ip) &&
  125. InstructionAddressSeemsValid(ip)) {
  126. *ip_found = ip;
  127. *location_found = location;
  128. return true;
  129. }
  130. }
  131. // nothing found
  132. return false;
  133. }
  134. // Information about the system that produced the minidump. Subclasses
  135. // and the SymbolSupplier may find this information useful.
  136. const SystemInfo *system_info_;
  137. // The stack memory to walk. Subclasses will require this region to
  138. // get information from the stack.
  139. MemoryRegion *memory_;
  140. // A list of modules, for populating each StackFrame's module information.
  141. // This field is optional and may be NULL.
  142. const CodeModules *modules_;
  143. protected:
  144. // The SourceLineResolver implementation.
  145. SourceLineResolverInterface *resolver_;
  146. private:
  147. // Obtains the context frame, the innermost called procedure in a stack
  148. // trace. Returns NULL on failure. GetContextFrame allocates a new
  149. // StackFrame (or StackFrame subclass), ownership of which is taken by
  150. // the caller.
  151. virtual StackFrame* GetContextFrame() = 0;
  152. // Obtains a caller frame. Each call to GetCallerFrame should return the
  153. // frame that called the last frame returned by GetContextFrame or
  154. // GetCallerFrame. To aid this purpose, stack contains the CallStack
  155. // made of frames that have already been walked. GetCallerFrame should
  156. // return NULL on failure or when there are no more caller frames (when
  157. // the end of the stack has been reached). GetCallerFrame allocates a new
  158. // StackFrame (or StackFrame subclass), ownership of which is taken by
  159. // the caller.
  160. virtual StackFrame* GetCallerFrame(const CallStack *stack) = 0;
  161. // The optional SymbolSupplier for resolving source line info.
  162. SymbolSupplier *supplier_;
  163. // A list of modules that we haven't found symbols for. We track
  164. // this in order to avoid repeatedly looking them up again within
  165. // one minidump.
  166. set<std::string> no_symbol_modules_;
  167. // The maximum number of frames Stackwalker will walk through.
  168. // This defaults to 1024 to prevent infinite loops.
  169. static u_int32_t max_frames_;
  170. };
  171. } // namespace google_breakpad
  172. #endif // GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__