toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/stackwalker.h

changeset 0
6474c204b198
     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__

mercurial