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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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.
    30 // stackwalker.h: Generic stackwalker.
    31 //
    32 // The Stackwalker class is an abstract base class providing common generic
    33 // methods that apply to stacks from all systems.  Specific implementations
    34 // will extend this class by providing GetContextFrame and GetCallerFrame
    35 // methods to fill in system-specific data in a StackFrame structure.
    36 // Stackwalker assembles these StackFrame strucutres into a CallStack.
    37 //
    38 // Author: Mark Mentovai
    41 #ifndef GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
    42 #define GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__
    44 #include <set>
    45 #include <string>
    46 #include <vector>
    48 #include "common/using_std_string.h"
    49 #include "google_breakpad/common/breakpad_types.h"
    50 #include "google_breakpad/processor/code_modules.h"
    51 #include "google_breakpad/processor/memory_region.h"
    52 #include "google_breakpad/processor/stack_frame_symbolizer.h"
    54 namespace google_breakpad {
    56 class CallStack;
    57 class MinidumpContext;
    58 class StackFrameSymbolizer;
    60 using std::set;
    61 using std::vector;
    63 class Stackwalker {
    64  public:
    65   virtual ~Stackwalker() {}
    67   // Populates the given CallStack by calling GetContextFrame and
    68   // GetCallerFrame.  The frames are further processed to fill all available
    69   // data.  Returns true if the stackwalk completed, or false if it was
    70   // interrupted by SymbolSupplier::GetSymbolFile().
    71   // Upon return, modules_without_symbols will be populated with pointers to
    72   // the code modules (CodeModule*) that DON'T have symbols.
    73   // modules_without_symbols DOES NOT take ownership of the code modules.
    74   // The lifetime of these code modules is the same as the lifetime of the
    75   // CodeModules passed to the StackWalker constructor (which currently
    76   // happens to be the lifetime of the Breakpad's ProcessingState object).
    77   // There is a check for duplicate modules so no duplicates are expected.
    78   bool Walk(CallStack* stack,
    79             vector<const CodeModule*>* modules_without_symbols);
    81   // Returns a new concrete subclass suitable for the CPU that a stack was
    82   // generated on, according to the CPU type indicated by the context
    83   // argument.  If no suitable concrete subclass exists, returns NULL.
    84   static Stackwalker* StackwalkerForCPU(
    85      const SystemInfo* system_info,
    86      MinidumpContext* context,
    87      MemoryRegion* memory,
    88      const CodeModules* modules,
    89      StackFrameSymbolizer* resolver_helper);
    91   static void set_max_frames(uint32_t max_frames) {
    92     max_frames_ = max_frames;
    93     max_frames_set_ = true;
    94   }
    95   static uint32_t max_frames() { return max_frames_; }
    97   static void set_max_frames_scanned(uint32_t max_frames_scanned) {
    98     max_frames_scanned_ = max_frames_scanned;
    99   }
   101  protected:
   102   // system_info identifies the operating system, NULL or empty if unknown.
   103   // memory identifies a MemoryRegion that provides the stack memory
   104   // for the stack to walk.  modules, if non-NULL, is a CodeModules
   105   // object that is used to look up which code module each stack frame is
   106   // associated with.  frame_symbolizer is a StackFrameSymbolizer object that
   107   // encapsulates the logic of how source line resolver interacts with symbol
   108   // supplier to symbolize stack frame and look up caller frame information
   109   // (see stack_frame_symbolizer.h).
   110   // frame_symbolizer MUST NOT be NULL (asserted).
   111   Stackwalker(const SystemInfo* system_info,
   112               MemoryRegion* memory,
   113               const CodeModules* modules,
   114               StackFrameSymbolizer* frame_symbolizer);
   116   // This can be used to filter out potential return addresses when
   117   // the stack walker resorts to stack scanning.
   118   // Returns true if any of:
   119   // * This address is within a loaded module, but we don't have symbols
   120   //   for that module.
   121   // * This address is within a loaded module for which we have symbols,
   122   //   and falls inside a function in that module.
   123   // Returns false otherwise.
   124   bool InstructionAddressSeemsValid(uint64_t address);
   126   // The default number of words to search through on the stack
   127   // for a return address.
   128   static const int kRASearchWords;
   130   template<typename InstructionType>
   131   bool ScanForReturnAddress(InstructionType location_start,
   132                             InstructionType* location_found,
   133                             InstructionType* ip_found) {
   134     return ScanForReturnAddress(location_start, location_found, ip_found,
   135                                 kRASearchWords);
   136   }
   138   // Scan the stack starting at location_start, looking for an address
   139   // that looks like a valid instruction pointer. Addresses must
   140   // 1) be contained in the current stack memory
   141   // 2) pass the checks in InstructionAddressSeemsValid
   142   //
   143   // Returns true if a valid-looking instruction pointer was found.
   144   // When returning true, sets location_found to the address at which
   145   // the value was found, and ip_found to the value contained at that
   146   // location in memory.
   147   template<typename InstructionType>
   148   bool ScanForReturnAddress(InstructionType location_start,
   149                             InstructionType* location_found,
   150                             InstructionType* ip_found,
   151                             int searchwords) {
   152     for (InstructionType location = location_start;
   153          location <= location_start + searchwords * sizeof(InstructionType);
   154          location += sizeof(InstructionType)) {
   155       InstructionType ip;
   156       if (!memory_->GetMemoryAtAddress(location, &ip))
   157         break;
   159       if (modules_ && modules_->GetModuleForAddress(ip) &&
   160           InstructionAddressSeemsValid(ip)) {
   161         *ip_found = ip;
   162         *location_found = location;
   163         return true;
   164       }
   165     }
   166     // nothing found
   167     return false;
   168   }
   170   // Information about the system that produced the minidump.  Subclasses
   171   // and the SymbolSupplier may find this information useful.
   172   const SystemInfo* system_info_;
   174   // The stack memory to walk.  Subclasses will require this region to
   175   // get information from the stack.
   176   MemoryRegion* memory_;
   178   // A list of modules, for populating each StackFrame's module information.
   179   // This field is optional and may be NULL.
   180   const CodeModules* modules_;
   182  protected:
   183   // The StackFrameSymbolizer implementation.
   184   StackFrameSymbolizer* frame_symbolizer_;
   186  private:
   187   // Obtains the context frame, the innermost called procedure in a stack
   188   // trace.  Returns NULL on failure.  GetContextFrame allocates a new
   189   // StackFrame (or StackFrame subclass), ownership of which is taken by
   190   // the caller.
   191   virtual StackFrame* GetContextFrame() = 0;
   193   // Obtains a caller frame.  Each call to GetCallerFrame should return the
   194   // frame that called the last frame returned by GetContextFrame or
   195   // GetCallerFrame.  To aid this purpose, stack contains the CallStack
   196   // made of frames that have already been walked.  GetCallerFrame should
   197   // return NULL on failure or when there are no more caller frames (when
   198   // the end of the stack has been reached).  GetCallerFrame allocates a new
   199   // StackFrame (or StackFrame subclass), ownership of which is taken by
   200   // the caller.  |stack_scan_allowed| controls whether stack scanning is
   201   // an allowable frame-recovery method, since it is desirable to be able to
   202   // disable stack scanning in performance-critical use cases.
   203   virtual StackFrame* GetCallerFrame(const CallStack* stack,
   204                                      bool stack_scan_allowed) = 0;
   206   // The maximum number of frames Stackwalker will walk through.
   207   // This defaults to 1024 to prevent infinite loops.
   208   static uint32_t max_frames_;
   210   // Keep track of whether max_frames_ has been set by the user, since
   211   // it affects whether or not an error message is printed in the case
   212   // where an unwind got stopped by the limit.
   213   static bool max_frames_set_;
   215   // The maximum number of stack-scanned and otherwise untrustworthy
   216   // frames allowed.  Stack-scanning can be expensive, so the option to
   217   // disable or limit it is helpful in cases where unwind performance is
   218   // important.  This defaults to 1024, the same as max_frames_.
   219   static uint32_t max_frames_scanned_;
   220 };
   222 }  // namespace google_breakpad
   225 #endif  // GOOGLE_BREAKPAD_PROCESSOR_STACKWALKER_H__

mercurial