1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stackwalker.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,225 @@ 1.4 +// Copyright (c) 2010 Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +// stackwalker.h: Generic stackwalker. 1.34 +// 1.35 +// The Stackwalker class is an abstract base class providing common generic 1.36 +// methods that apply to stacks from all systems. Specific implementations 1.37 +// will extend this class by providing GetContextFrame and GetCallerFrame 1.38 +// methods to fill in system-specific data in a StackFrame structure. 1.39 +// Stackwalker assembles these StackFrame strucutres into a CallStack. 1.40 +// 1.41 +// Author: Mark Mentovai 1.42 + 1.43 + 1.44 +#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__ 1.45 +#define GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__ 1.46 + 1.47 +#include <set> 1.48 +#include <string> 1.49 +#include <vector> 1.50 + 1.51 +#include "common/using_std_string.h" 1.52 +#include "google_breakpad/common/breakpad_types.h" 1.53 +#include "google_breakpad/processor/code_modules.h" 1.54 +#include "google_breakpad/processor/memory_region.h" 1.55 +#include "google_breakpad/processor/stack_frame_symbolizer.h" 1.56 + 1.57 +namespace google_breakpad { 1.58 + 1.59 +class CallStack; 1.60 +class MinidumpContext; 1.61 +class StackFrameSymbolizer; 1.62 + 1.63 +using std::set; 1.64 +using std::vector; 1.65 + 1.66 +class Stackwalker { 1.67 + public: 1.68 + virtual ~Stackwalker() {} 1.69 + 1.70 + // Populates the given CallStack by calling GetContextFrame and 1.71 + // GetCallerFrame. The frames are further processed to fill all available 1.72 + // data. Returns true if the stackwalk completed, or false if it was 1.73 + // interrupted by SymbolSupplier::GetSymbolFile(). 1.74 + // Upon return, modules_without_symbols will be populated with pointers to 1.75 + // the code modules (CodeModule*) that DON'T have symbols. 1.76 + // modules_without_symbols DOES NOT take ownership of the code modules. 1.77 + // The lifetime of these code modules is the same as the lifetime of the 1.78 + // CodeModules passed to the StackWalker constructor (which currently 1.79 + // happens to be the lifetime of the Breakpad's ProcessingState object). 1.80 + // There is a check for duplicate modules so no duplicates are expected. 1.81 + bool Walk(CallStack* stack, 1.82 + vector<const CodeModule*>* modules_without_symbols); 1.83 + 1.84 + // Returns a new concrete subclass suitable for the CPU that a stack was 1.85 + // generated on, according to the CPU type indicated by the context 1.86 + // argument. If no suitable concrete subclass exists, returns NULL. 1.87 + static Stackwalker* StackwalkerForCPU( 1.88 + const SystemInfo* system_info, 1.89 + MinidumpContext* context, 1.90 + MemoryRegion* memory, 1.91 + const CodeModules* modules, 1.92 + StackFrameSymbolizer* resolver_helper); 1.93 + 1.94 + static void set_max_frames(uint32_t max_frames) { 1.95 + max_frames_ = max_frames; 1.96 + max_frames_set_ = true; 1.97 + } 1.98 + static uint32_t max_frames() { return max_frames_; } 1.99 + 1.100 + static void set_max_frames_scanned(uint32_t max_frames_scanned) { 1.101 + max_frames_scanned_ = max_frames_scanned; 1.102 + } 1.103 + 1.104 + protected: 1.105 + // system_info identifies the operating system, NULL or empty if unknown. 1.106 + // memory identifies a MemoryRegion that provides the stack memory 1.107 + // for the stack to walk. modules, if non-NULL, is a CodeModules 1.108 + // object that is used to look up which code module each stack frame is 1.109 + // associated with. frame_symbolizer is a StackFrameSymbolizer object that 1.110 + // encapsulates the logic of how source line resolver interacts with symbol 1.111 + // supplier to symbolize stack frame and look up caller frame information 1.112 + // (see stack_frame_symbolizer.h). 1.113 + // frame_symbolizer MUST NOT be NULL (asserted). 1.114 + Stackwalker(const SystemInfo* system_info, 1.115 + MemoryRegion* memory, 1.116 + const CodeModules* modules, 1.117 + StackFrameSymbolizer* frame_symbolizer); 1.118 + 1.119 + // This can be used to filter out potential return addresses when 1.120 + // the stack walker resorts to stack scanning. 1.121 + // Returns true if any of: 1.122 + // * This address is within a loaded module, but we don't have symbols 1.123 + // for that module. 1.124 + // * This address is within a loaded module for which we have symbols, 1.125 + // and falls inside a function in that module. 1.126 + // Returns false otherwise. 1.127 + bool InstructionAddressSeemsValid(uint64_t address); 1.128 + 1.129 + // The default number of words to search through on the stack 1.130 + // for a return address. 1.131 + static const int kRASearchWords; 1.132 + 1.133 + template<typename InstructionType> 1.134 + bool ScanForReturnAddress(InstructionType location_start, 1.135 + InstructionType* location_found, 1.136 + InstructionType* ip_found) { 1.137 + return ScanForReturnAddress(location_start, location_found, ip_found, 1.138 + kRASearchWords); 1.139 + } 1.140 + 1.141 + // Scan the stack starting at location_start, looking for an address 1.142 + // that looks like a valid instruction pointer. Addresses must 1.143 + // 1) be contained in the current stack memory 1.144 + // 2) pass the checks in InstructionAddressSeemsValid 1.145 + // 1.146 + // Returns true if a valid-looking instruction pointer was found. 1.147 + // When returning true, sets location_found to the address at which 1.148 + // the value was found, and ip_found to the value contained at that 1.149 + // location in memory. 1.150 + template<typename InstructionType> 1.151 + bool ScanForReturnAddress(InstructionType location_start, 1.152 + InstructionType* location_found, 1.153 + InstructionType* ip_found, 1.154 + int searchwords) { 1.155 + for (InstructionType location = location_start; 1.156 + location <= location_start + searchwords * sizeof(InstructionType); 1.157 + location += sizeof(InstructionType)) { 1.158 + InstructionType ip; 1.159 + if (!memory_->GetMemoryAtAddress(location, &ip)) 1.160 + break; 1.161 + 1.162 + if (modules_ && modules_->GetModuleForAddress(ip) && 1.163 + InstructionAddressSeemsValid(ip)) { 1.164 + *ip_found = ip; 1.165 + *location_found = location; 1.166 + return true; 1.167 + } 1.168 + } 1.169 + // nothing found 1.170 + return false; 1.171 + } 1.172 + 1.173 + // Information about the system that produced the minidump. Subclasses 1.174 + // and the SymbolSupplier may find this information useful. 1.175 + const SystemInfo* system_info_; 1.176 + 1.177 + // The stack memory to walk. Subclasses will require this region to 1.178 + // get information from the stack. 1.179 + MemoryRegion* memory_; 1.180 + 1.181 + // A list of modules, for populating each StackFrame's module information. 1.182 + // This field is optional and may be NULL. 1.183 + const CodeModules* modules_; 1.184 + 1.185 + protected: 1.186 + // The StackFrameSymbolizer implementation. 1.187 + StackFrameSymbolizer* frame_symbolizer_; 1.188 + 1.189 + private: 1.190 + // Obtains the context frame, the innermost called procedure in a stack 1.191 + // trace. Returns NULL on failure. GetContextFrame allocates a new 1.192 + // StackFrame (or StackFrame subclass), ownership of which is taken by 1.193 + // the caller. 1.194 + virtual StackFrame* GetContextFrame() = 0; 1.195 + 1.196 + // Obtains a caller frame. Each call to GetCallerFrame should return the 1.197 + // frame that called the last frame returned by GetContextFrame or 1.198 + // GetCallerFrame. To aid this purpose, stack contains the CallStack 1.199 + // made of frames that have already been walked. GetCallerFrame should 1.200 + // return NULL on failure or when there are no more caller frames (when 1.201 + // the end of the stack has been reached). GetCallerFrame allocates a new 1.202 + // StackFrame (or StackFrame subclass), ownership of which is taken by 1.203 + // the caller. |stack_scan_allowed| controls whether stack scanning is 1.204 + // an allowable frame-recovery method, since it is desirable to be able to 1.205 + // disable stack scanning in performance-critical use cases. 1.206 + virtual StackFrame* GetCallerFrame(const CallStack* stack, 1.207 + bool stack_scan_allowed) = 0; 1.208 + 1.209 + // The maximum number of frames Stackwalker will walk through. 1.210 + // This defaults to 1024 to prevent infinite loops. 1.211 + static uint32_t max_frames_; 1.212 + 1.213 + // Keep track of whether max_frames_ has been set by the user, since 1.214 + // it affects whether or not an error message is printed in the case 1.215 + // where an unwind got stopped by the limit. 1.216 + static bool max_frames_set_; 1.217 + 1.218 + // The maximum number of stack-scanned and otherwise untrustworthy 1.219 + // frames allowed. Stack-scanning can be expensive, so the option to 1.220 + // disable or limit it is helpful in cases where unwind performance is 1.221 + // important. This defaults to 1024, the same as max_frames_. 1.222 + static uint32_t max_frames_scanned_; 1.223 +}; 1.224 + 1.225 +} // namespace google_breakpad 1.226 + 1.227 + 1.228 +#endif // GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__