toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/processor/stackwalker_x86.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,625 @@
     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_x86.cc: x86-specific stackwalker.
    1.34 +//
    1.35 +// See stackwalker_x86.h for documentation.
    1.36 +//
    1.37 +// Author: Mark Mentovai
    1.38 +
    1.39 +#include <assert.h>
    1.40 +#include <string>
    1.41 +
    1.42 +#include "common/scoped_ptr.h"
    1.43 +#include "google_breakpad/processor/call_stack.h"
    1.44 +#include "google_breakpad/processor/code_modules.h"
    1.45 +#include "google_breakpad/processor/memory_region.h"
    1.46 +#include "google_breakpad/processor/source_line_resolver_interface.h"
    1.47 +#include "google_breakpad/processor/stack_frame_cpu.h"
    1.48 +#include "common/logging.h"
    1.49 +#include "processor/postfix_evaluator-inl.h"
    1.50 +#include "processor/stackwalker_x86.h"
    1.51 +#include "processor/windows_frame_info.h"
    1.52 +#include "processor/cfi_frame_info.h"
    1.53 +
    1.54 +namespace google_breakpad {
    1.55 +
    1.56 +
    1.57 +const StackwalkerX86::CFIWalker::RegisterSet
    1.58 +StackwalkerX86::cfi_register_map_[] = {
    1.59 +  // It may seem like $eip and $esp are callee-saves, because (with Unix or
    1.60 +  // cdecl calling conventions) the callee is responsible for having them
    1.61 +  // restored upon return. But the callee_saves flags here really means
    1.62 +  // that the walker should assume they're unchanged if the CFI doesn't
    1.63 +  // mention them, which is clearly wrong for $eip and $esp.
    1.64 +  { ToUniqueString("$eip"), ToUniqueString(".ra"),  false,
    1.65 +    StackFrameX86::CONTEXT_VALID_EIP, &MDRawContextX86::eip },
    1.66 +  { ToUniqueString("$esp"), ToUniqueString(".cfa"), false,
    1.67 +    StackFrameX86::CONTEXT_VALID_ESP, &MDRawContextX86::esp },
    1.68 +  { ToUniqueString("$ebp"), NULL,   true,
    1.69 +    StackFrameX86::CONTEXT_VALID_EBP, &MDRawContextX86::ebp },
    1.70 +  { ToUniqueString("$eax"), NULL,   false,
    1.71 +    StackFrameX86::CONTEXT_VALID_EAX, &MDRawContextX86::eax },
    1.72 +  { ToUniqueString("$ebx"), NULL,   true,
    1.73 +    StackFrameX86::CONTEXT_VALID_EBX, &MDRawContextX86::ebx },
    1.74 +  { ToUniqueString("$ecx"), NULL,   false,
    1.75 +    StackFrameX86::CONTEXT_VALID_ECX, &MDRawContextX86::ecx },
    1.76 +  { ToUniqueString("$edx"), NULL,   false,
    1.77 +    StackFrameX86::CONTEXT_VALID_EDX, &MDRawContextX86::edx },
    1.78 +  { ToUniqueString("$esi"), NULL,   true,
    1.79 +    StackFrameX86::CONTEXT_VALID_ESI, &MDRawContextX86::esi },
    1.80 +  { ToUniqueString("$edi"), NULL,   true,
    1.81 +    StackFrameX86::CONTEXT_VALID_EDI, &MDRawContextX86::edi },
    1.82 +};
    1.83 +
    1.84 +StackwalkerX86::StackwalkerX86(const SystemInfo* system_info,
    1.85 +                               const MDRawContextX86* context,
    1.86 +                               MemoryRegion* memory,
    1.87 +                               const CodeModules* modules,
    1.88 +                               StackFrameSymbolizer* resolver_helper)
    1.89 +    : Stackwalker(system_info, memory, modules, resolver_helper),
    1.90 +      context_(context),
    1.91 +      cfi_walker_(cfi_register_map_,
    1.92 +                  (sizeof(cfi_register_map_) / sizeof(cfi_register_map_[0]))) {
    1.93 +  if (memory_ && memory_->GetBase() + memory_->GetSize() - 1 > 0xffffffff) {
    1.94 +    // The x86 is a 32-bit CPU, the limits of the supplied stack are invalid.
    1.95 +    // Mark memory_ = NULL, which will cause stackwalking to fail.
    1.96 +    BPLOG(ERROR) << "Memory out of range for stackwalking: " <<
    1.97 +                    HexString(memory_->GetBase()) << "+" <<
    1.98 +                    HexString(memory_->GetSize());
    1.99 +    memory_ = NULL;
   1.100 +  }
   1.101 +}
   1.102 +
   1.103 +StackFrameX86::~StackFrameX86() {
   1.104 +  if (windows_frame_info)
   1.105 +    delete windows_frame_info;
   1.106 +  windows_frame_info = NULL;
   1.107 +  if (cfi_frame_info)
   1.108 +    delete cfi_frame_info;
   1.109 +  cfi_frame_info = NULL;
   1.110 +}
   1.111 +
   1.112 +uint64_t StackFrameX86::ReturnAddress() const
   1.113 +{
   1.114 +  assert(context_validity & StackFrameX86::CONTEXT_VALID_EIP);
   1.115 +  return context.eip;   
   1.116 +}
   1.117 +
   1.118 +StackFrame* StackwalkerX86::GetContextFrame() {
   1.119 +  if (!context_) {
   1.120 +    BPLOG(ERROR) << "Can't get context frame without context";
   1.121 +    return NULL;
   1.122 +  }
   1.123 +
   1.124 +  StackFrameX86* frame = new StackFrameX86();
   1.125 +
   1.126 +  // The instruction pointer is stored directly in a register, so pull it
   1.127 +  // straight out of the CPU context structure.
   1.128 +  frame->context = *context_;
   1.129 +  frame->context_validity = StackFrameX86::CONTEXT_VALID_ALL;
   1.130 +  frame->trust = StackFrame::FRAME_TRUST_CONTEXT;
   1.131 +  frame->instruction = frame->context.eip;
   1.132 +
   1.133 +  return frame;
   1.134 +}
   1.135 +
   1.136 +StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo(
   1.137 +    const vector<StackFrame*> &frames,
   1.138 +    WindowsFrameInfo* last_frame_info,
   1.139 +    bool stack_scan_allowed) {
   1.140 +  StackFrame::FrameTrust trust = StackFrame::FRAME_TRUST_NONE;
   1.141 +
   1.142 +  StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
   1.143 +
   1.144 +  // Save the stack walking info we found, in case we need it later to
   1.145 +  // find the callee of the frame we're constructing now.
   1.146 +  last_frame->windows_frame_info = last_frame_info;
   1.147 +
   1.148 +  // This function only covers the full STACK WIN case. If
   1.149 +  // last_frame_info is VALID_PARAMETER_SIZE-only, then we should
   1.150 +  // assume the traditional frame format or use some other strategy.
   1.151 +  if (last_frame_info->valid != WindowsFrameInfo::VALID_ALL)
   1.152 +    return NULL;
   1.153 +
   1.154 +  // This stackwalker sets each frame's %esp to its value immediately prior
   1.155 +  // to the CALL into the callee.  This means that %esp points to the last
   1.156 +  // callee argument pushed onto the stack, which may not be where %esp points
   1.157 +  // after the callee returns.  Specifically, the value is correct for the
   1.158 +  // cdecl calling convention, but not other conventions.  The cdecl
   1.159 +  // convention requires a caller to pop its callee's arguments from the
   1.160 +  // stack after the callee returns.  This is usually accomplished by adding
   1.161 +  // the known size of the arguments to %esp.  Other calling conventions,
   1.162 +  // including stdcall, thiscall, and fastcall, require the callee to pop any
   1.163 +  // parameters stored on the stack before returning.  This is usually
   1.164 +  // accomplished by using the RET n instruction, which pops n bytes off
   1.165 +  // the stack after popping the return address.
   1.166 +  //
   1.167 +  // Because each frame's %esp will point to a location on the stack after
   1.168 +  // callee arguments have been PUSHed, when locating things in a stack frame
   1.169 +  // relative to %esp, the size of the arguments to the callee need to be
   1.170 +  // taken into account.  This seems a little bit unclean, but it's better
   1.171 +  // than the alternative, which would need to take these same things into
   1.172 +  // account, but only for cdecl functions.  With this implementation, we get
   1.173 +  // to be agnostic about each function's calling convention.  Furthermore,
   1.174 +  // this is how Windows debugging tools work, so it means that the %esp
   1.175 +  // values produced by this stackwalker directly correspond to the %esp
   1.176 +  // values you'll see there.
   1.177 +  //
   1.178 +  // If the last frame has no callee (because it's the context frame), just
   1.179 +  // set the callee parameter size to 0: the stack pointer can't point to
   1.180 +  // callee arguments because there's no callee.  This is correct as long
   1.181 +  // as the context wasn't captured while arguments were being pushed for
   1.182 +  // a function call.  Note that there may be functions whose parameter sizes
   1.183 +  // are unknown, 0 is also used in that case.  When that happens, it should
   1.184 +  // be possible to walk to the next frame without reference to %esp.
   1.185 +
   1.186 +  uint32_t last_frame_callee_parameter_size = 0;
   1.187 +  int frames_already_walked = frames.size();
   1.188 +  if (frames_already_walked >= 2) {
   1.189 +    const StackFrameX86* last_frame_callee
   1.190 +        = static_cast<StackFrameX86*>(frames[frames_already_walked - 2]);
   1.191 +    WindowsFrameInfo* last_frame_callee_info
   1.192 +        = last_frame_callee->windows_frame_info;
   1.193 +    if (last_frame_callee_info &&
   1.194 +        (last_frame_callee_info->valid
   1.195 +         & WindowsFrameInfo::VALID_PARAMETER_SIZE)) {
   1.196 +      last_frame_callee_parameter_size =
   1.197 +          last_frame_callee_info->parameter_size;
   1.198 +    }
   1.199 +  }
   1.200 +
   1.201 +  // Set up the dictionary for the PostfixEvaluator.  %ebp and %esp are used
   1.202 +  // in each program string, and their previous values are known, so set them
   1.203 +  // here.
   1.204 +  PostfixEvaluator<uint32_t>::DictionaryType dictionary;
   1.205 +  // Provide the current register values.
   1.206 +  dictionary.set(ustr__ZSebp(), last_frame->context.ebp);
   1.207 +  dictionary.set(ustr__ZSesp(), last_frame->context.esp);
   1.208 +  // Provide constants from the debug info for last_frame and its callee.
   1.209 +  // .cbCalleeParams is a Breakpad extension that allows us to use the
   1.210 +  // PostfixEvaluator engine when certain types of debugging information
   1.211 +  // are present without having to write the constants into the program
   1.212 +  // string as literals.
   1.213 +  dictionary.set(ustr__ZDcbCalleeParams(), last_frame_callee_parameter_size);
   1.214 +  dictionary.set(ustr__ZDcbSavedRegs(), last_frame_info->saved_register_size);
   1.215 +  dictionary.set(ustr__ZDcbLocals(), last_frame_info->local_size);
   1.216 +
   1.217 +  uint32_t raSearchStart = last_frame->context.esp +
   1.218 +                            last_frame_callee_parameter_size +
   1.219 +                            last_frame_info->local_size +
   1.220 +                            last_frame_info->saved_register_size;
   1.221 +
   1.222 +  uint32_t raSearchStartOld = raSearchStart;
   1.223 +  uint32_t found = 0;  // dummy value
   1.224 +  // Scan up to three words above the calculated search value, in case
   1.225 +  // the stack was aligned to a quadword boundary.
   1.226 +  if (ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3) &&
   1.227 +      last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT &&
   1.228 +      last_frame->windows_frame_info != NULL &&
   1.229 +      last_frame_info->type_ == WindowsFrameInfo::STACK_INFO_FPO &&
   1.230 +      raSearchStartOld == raSearchStart &&
   1.231 +      found == last_frame->context.eip) {
   1.232 +    // The context frame represents an FPO-optimized Windows system call.
   1.233 +    // On the top of the stack we have a pointer to the current instruction.
   1.234 +    // This means that the callee has returned but the return address is still
   1.235 +    // on the top of the stack which is very atypical situaltion.
   1.236 +    // Skip one slot from the stack and do another scan in order to get the
   1.237 +    // actual return address.
   1.238 +    raSearchStart += 4;
   1.239 +    ScanForReturnAddress(raSearchStart, &raSearchStart, &found, 3);
   1.240 +  }
   1.241 +
   1.242 +  // The difference between raSearch and raSearchStart is unknown,
   1.243 +  // but making them the same seems to work well in practice.
   1.244 +  dictionary.set(ustr__ZDraSearchStart(), raSearchStart);
   1.245 +  dictionary.set(ustr__ZDraSearch(), raSearchStart);
   1.246 +
   1.247 +  dictionary.set(ustr__ZDcbParams(), last_frame_info->parameter_size);
   1.248 +
   1.249 +  // Decide what type of program string to use. The program string is in
   1.250 +  // postfix notation and will be passed to PostfixEvaluator::Evaluate.
   1.251 +  // Given the dictionary and the program string, it is possible to compute
   1.252 +  // the return address and the values of other registers in the calling
   1.253 +  // function. Because of bugs described below, the stack may need to be
   1.254 +  // scanned for these values. The results of program string evaluation
   1.255 +  // will be used to determine whether to scan for better values.
   1.256 +  string program_string;
   1.257 +  bool recover_ebp = true;
   1.258 +
   1.259 +  trust = StackFrame::FRAME_TRUST_CFI;
   1.260 +  if (!last_frame_info->program_string.empty()) {
   1.261 +    // The FPO data has its own program string, which will tell us how to
   1.262 +    // get to the caller frame, and may even fill in the values of
   1.263 +    // nonvolatile registers and provide pointers to local variables and
   1.264 +    // parameters.  In some cases, particularly with program strings that use
   1.265 +    // .raSearchStart, the stack may need to be scanned afterward.
   1.266 +    program_string = last_frame_info->program_string;
   1.267 +  } else if (last_frame_info->allocates_base_pointer) {
   1.268 +    // The function corresponding to the last frame doesn't use the frame
   1.269 +    // pointer for conventional purposes, but it does allocate a new
   1.270 +    // frame pointer and use it for its own purposes.  Its callee's
   1.271 +    // information is still accessed relative to %esp, and the previous
   1.272 +    // value of %ebp can be recovered from a location in its stack frame,
   1.273 +    // within the saved-register area.
   1.274 +    //
   1.275 +    // Functions that fall into this category use the %ebp register for
   1.276 +    // a purpose other than the frame pointer.  They restore the caller's
   1.277 +    // %ebp before returning.  These functions create their stack frame
   1.278 +    // after a CALL by decrementing the stack pointer in an amount
   1.279 +    // sufficient to store local variables, and then PUSHing saved
   1.280 +    // registers onto the stack.  Arguments to a callee function, if any,
   1.281 +    // are PUSHed after that.  Walking up to the caller, therefore,
   1.282 +    // can be done solely with calculations relative to the stack pointer
   1.283 +    // (%esp).  The return address is recovered from the memory location
   1.284 +    // above the known sizes of the callee's parameters, saved registers,
   1.285 +    // and locals.  The caller's stack pointer (the value of %esp when
   1.286 +    // the caller executed CALL) is the location immediately above the
   1.287 +    // saved return address.  The saved value of %ebp to be restored for
   1.288 +    // the caller is at a known location in the saved-register area of
   1.289 +    // the stack frame.
   1.290 +    //
   1.291 +    // For this type of frame, MSVC 14 (from Visual Studio 8/2005) in
   1.292 +    // link-time code generation mode (/LTCG and /GL) can generate erroneous
   1.293 +    // debugging data.  The reported size of saved registers can be 0,
   1.294 +    // which is clearly an error because these frames must, at the very
   1.295 +    // least, save %ebp.  For this reason, in addition to those given above
   1.296 +    // about the use of .raSearchStart, the stack may need to be scanned
   1.297 +    // for a better return address and a better frame pointer after the
   1.298 +    // program string is evaluated.
   1.299 +    //
   1.300 +    // %eip_new = *(%esp_old + callee_params + saved_regs + locals)
   1.301 +    // %ebp_new = *(%esp_old + callee_params + saved_regs - 8)
   1.302 +    // %esp_new = %esp_old + callee_params + saved_regs + locals + 4
   1.303 +    program_string = "$eip .raSearchStart ^ = "
   1.304 +        "$ebp $esp .cbCalleeParams + .cbSavedRegs + 8 - ^ = "
   1.305 +        "$esp .raSearchStart 4 + =";
   1.306 +  } else {
   1.307 +    // The function corresponding to the last frame doesn't use %ebp at
   1.308 +    // all.  The callee frame is located relative to %esp.
   1.309 +    //
   1.310 +    // The called procedure's instruction pointer and stack pointer are
   1.311 +    // recovered in the same way as the case above, except that no
   1.312 +    // frame pointer (%ebp) is used at all, so it is not saved anywhere
   1.313 +    // in the callee's stack frame and does not need to be recovered.
   1.314 +    // Because %ebp wasn't used in the callee, whatever value it has
   1.315 +    // is the value that it had in the caller, so it can be carried
   1.316 +    // straight through without bringing its validity into question.
   1.317 +    //
   1.318 +    // Because of the use of .raSearchStart, the stack will possibly be
   1.319 +    // examined to locate a better return address after program string
   1.320 +    // evaluation.  The stack will not be examined to locate a saved
   1.321 +    // %ebp value, because these frames do not save (or use) %ebp.
   1.322 +    //
   1.323 +    // %eip_new = *(%esp_old + callee_params + saved_regs + locals)
   1.324 +    // %esp_new = %esp_old + callee_params + saved_regs + locals + 4
   1.325 +    // %ebp_new = %ebp_old
   1.326 +    program_string = "$eip .raSearchStart ^ = "
   1.327 +        "$esp .raSearchStart 4 + =";
   1.328 +    recover_ebp = false;
   1.329 +  }
   1.330 +
   1.331 +  // Now crank it out, making sure that the program string set at least the
   1.332 +  // two required variables.
   1.333 +  PostfixEvaluator<uint32_t> evaluator =
   1.334 +      PostfixEvaluator<uint32_t>(&dictionary, memory_);
   1.335 +  PostfixEvaluator<uint32_t>::DictionaryValidityType dictionary_validity;
   1.336 +  if (!evaluator.Evaluate(program_string, &dictionary_validity) ||
   1.337 +      !dictionary_validity.have(ustr__ZSeip()) ||
   1.338 +      !dictionary_validity.have(ustr__ZSesp())) {
   1.339 +    // Program string evaluation failed. It may be that %eip is not somewhere
   1.340 +    // with stack frame info, and %ebp is pointing to non-stack memory, so
   1.341 +    // our evaluation couldn't succeed. We'll scan the stack for a return
   1.342 +    // address. This can happen if the stack is in a module for which
   1.343 +    // we don't have symbols, and that module is compiled without a
   1.344 +    // frame pointer.
   1.345 +    uint32_t location_start = last_frame->context.esp;
   1.346 +    uint32_t location, eip;
   1.347 +    if (!stack_scan_allowed
   1.348 +        || !ScanForReturnAddress(location_start, &location, &eip)) {
   1.349 +      // if we can't find an instruction pointer even with stack scanning,
   1.350 +      // give up.
   1.351 +      return NULL;
   1.352 +    }
   1.353 +
   1.354 +    // This seems like a reasonable return address. Since program string
   1.355 +    // evaluation failed, use it and set %esp to the location above the
   1.356 +    // one where the return address was found.
   1.357 +    dictionary.set(ustr__ZSeip(), eip);
   1.358 +    dictionary.set(ustr__ZSesp(), location + 4);
   1.359 +    trust = StackFrame::FRAME_TRUST_SCAN;
   1.360 +  }
   1.361 +
   1.362 +  // Since this stack frame did not use %ebp in a traditional way,
   1.363 +  // locating the return address isn't entirely deterministic. In that
   1.364 +  // case, the stack can be scanned to locate the return address.
   1.365 +  //
   1.366 +  // However, if program string evaluation resulted in both %eip and
   1.367 +  // %ebp values of 0, trust that the end of the stack has been
   1.368 +  // reached and don't scan for anything else.
   1.369 +  if (dictionary.get(ustr__ZSeip()) != 0 ||
   1.370 +      dictionary.get(ustr__ZSebp()) != 0) {
   1.371 +    int offset = 0;
   1.372 +
   1.373 +    // This scan can only be done if a CodeModules object is available, to
   1.374 +    // check that candidate return addresses are in fact inside a module.
   1.375 +    //
   1.376 +    // TODO(mmentovai): This ignores dynamically-generated code.  One possible
   1.377 +    // solution is to check the minidump's memory map to see if the candidate
   1.378 +    // %eip value comes from a mapped executable page, although this would
   1.379 +    // require dumps that contain MINIDUMP_MEMORY_INFO, which the Breakpad
   1.380 +    // client doesn't currently write (it would need to call MiniDumpWriteDump
   1.381 +    // with the MiniDumpWithFullMemoryInfo type bit set).  Even given this
   1.382 +    // ability, older OSes (pre-XP SP2) and CPUs (pre-P4) don't enforce
   1.383 +    // an independent execute privilege on memory pages.
   1.384 +
   1.385 +    uint32_t eip = dictionary.get(ustr__ZSeip());
   1.386 +    if (modules_ && !modules_->GetModuleForAddress(eip)) {
   1.387 +      // The instruction pointer at .raSearchStart was invalid, so start
   1.388 +      // looking one 32-bit word above that location.
   1.389 +      uint32_t location_start = dictionary.get(ustr__ZDraSearchStart()) + 4;
   1.390 +      uint32_t location;
   1.391 +      if (stack_scan_allowed
   1.392 +          && ScanForReturnAddress(location_start, &location, &eip)) {
   1.393 +        // This is a better return address that what program string
   1.394 +        // evaluation found.  Use it, and set %esp to the location above the
   1.395 +        // one where the return address was found.
   1.396 +        dictionary.set(ustr__ZSeip(), eip);
   1.397 +        dictionary.set(ustr__ZSesp(), location + 4);
   1.398 +        offset = location - location_start;
   1.399 +        trust = StackFrame::FRAME_TRUST_CFI_SCAN;
   1.400 +      }
   1.401 +    }
   1.402 +
   1.403 +    if (recover_ebp) {
   1.404 +      // When trying to recover the previous value of the frame pointer (%ebp),
   1.405 +      // start looking at the lowest possible address in the saved-register
   1.406 +      // area, and look at the entire saved register area, increased by the
   1.407 +      // size of |offset| to account for additional data that may be on the
   1.408 +      // stack.  The scan is performed from the highest possible address to
   1.409 +      // the lowest, because the expectation is that the function's prolog
   1.410 +      // would have saved %ebp early.
   1.411 +      uint32_t ebp = dictionary.get(ustr__ZSebp());
   1.412 +
   1.413 +      // When a scan for return address is used, it is possible to skip one or
   1.414 +      // more frames (when return address is not in a known module).  One
   1.415 +      // indication for skipped frames is when the value of %ebp is lower than
   1.416 +      // the location of the return address on the stack
   1.417 +      bool has_skipped_frames =
   1.418 +        (trust != StackFrame::FRAME_TRUST_CFI && ebp <= raSearchStart + offset);
   1.419 +
   1.420 +      uint32_t value;  // throwaway variable to check pointer validity
   1.421 +      if (has_skipped_frames || !memory_->GetMemoryAtAddress(ebp, &value)) {
   1.422 +        int fp_search_bytes = last_frame_info->saved_register_size + offset;
   1.423 +        uint32_t location_end = last_frame->context.esp +
   1.424 +                                 last_frame_callee_parameter_size;
   1.425 +
   1.426 +        for (uint32_t location = location_end + fp_search_bytes;
   1.427 +             location >= location_end;
   1.428 +             location -= 4) {
   1.429 +          if (!memory_->GetMemoryAtAddress(location, &ebp))
   1.430 +            break;
   1.431 +
   1.432 +          if (memory_->GetMemoryAtAddress(ebp, &value)) {
   1.433 +            // The candidate value is a pointer to the same memory region
   1.434 +            // (the stack).  Prefer it as a recovered %ebp result.
   1.435 +            dictionary.set(ustr__ZSebp(), ebp);
   1.436 +            break;
   1.437 +          }
   1.438 +        }
   1.439 +      }
   1.440 +    }
   1.441 +  }
   1.442 +
   1.443 +  // Create a new stack frame (ownership will be transferred to the caller)
   1.444 +  // and fill it in.
   1.445 +  StackFrameX86* frame = new StackFrameX86();
   1.446 +
   1.447 +  frame->trust = trust;
   1.448 +  frame->context = last_frame->context;
   1.449 +  frame->context.eip = dictionary.get(ustr__ZSeip());
   1.450 +  frame->context.esp = dictionary.get(ustr__ZSesp());
   1.451 +  frame->context.ebp = dictionary.get(ustr__ZSebp());
   1.452 +  frame->context_validity = StackFrameX86::CONTEXT_VALID_EIP |
   1.453 +                                StackFrameX86::CONTEXT_VALID_ESP |
   1.454 +                                StackFrameX86::CONTEXT_VALID_EBP;
   1.455 +
   1.456 +  // These are nonvolatile (callee-save) registers, and the program string
   1.457 +  // may have filled them in.
   1.458 +  if (dictionary_validity.have(ustr__ZSebx())) {
   1.459 +    frame->context.ebx = dictionary.get(ustr__ZSebx());
   1.460 +    frame->context_validity |= StackFrameX86::CONTEXT_VALID_EBX;
   1.461 +  }
   1.462 +  if (dictionary_validity.have(ustr__ZSesi())) {
   1.463 +    frame->context.esi = dictionary.get(ustr__ZSesi());
   1.464 +    frame->context_validity |= StackFrameX86::CONTEXT_VALID_ESI;
   1.465 +  }
   1.466 +  if (dictionary_validity.have(ustr__ZSedi())) {
   1.467 +    frame->context.edi = dictionary.get(ustr__ZSedi());
   1.468 +    frame->context_validity |= StackFrameX86::CONTEXT_VALID_EDI;
   1.469 +  }
   1.470 +
   1.471 +  return frame;
   1.472 +}
   1.473 +
   1.474 +StackFrameX86* StackwalkerX86::GetCallerByCFIFrameInfo(
   1.475 +    const vector<StackFrame*> &frames,
   1.476 +    CFIFrameInfo* cfi_frame_info) {
   1.477 +  StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
   1.478 +  last_frame->cfi_frame_info = cfi_frame_info;
   1.479 +
   1.480 +  scoped_ptr<StackFrameX86> frame(new StackFrameX86());
   1.481 +  if (!cfi_walker_
   1.482 +      .FindCallerRegisters(*memory_, *cfi_frame_info,
   1.483 +                           last_frame->context, last_frame->context_validity,
   1.484 +                           &frame->context, &frame->context_validity))
   1.485 +    return NULL;
   1.486 +
   1.487 +  // Make sure we recovered all the essentials.
   1.488 +  static const int essentials = (StackFrameX86::CONTEXT_VALID_EIP
   1.489 +                                 | StackFrameX86::CONTEXT_VALID_ESP
   1.490 +                                 | StackFrameX86::CONTEXT_VALID_EBP);
   1.491 +  if ((frame->context_validity & essentials) != essentials)
   1.492 +    return NULL;
   1.493 +
   1.494 +  frame->trust = StackFrame::FRAME_TRUST_CFI;
   1.495 +
   1.496 +  return frame.release();
   1.497 +}
   1.498 +
   1.499 +StackFrameX86* StackwalkerX86::GetCallerByEBPAtBase(
   1.500 +    const vector<StackFrame*> &frames,
   1.501 +    bool stack_scan_allowed) {
   1.502 +  StackFrame::FrameTrust trust;
   1.503 +  StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
   1.504 +  uint32_t last_esp = last_frame->context.esp;
   1.505 +  uint32_t last_ebp = last_frame->context.ebp;
   1.506 +
   1.507 +  // Assume that the standard %ebp-using x86 calling convention is in
   1.508 +  // use.
   1.509 +  //
   1.510 +  // The typical x86 calling convention, when frame pointers are present,
   1.511 +  // is for the calling procedure to use CALL, which pushes the return
   1.512 +  // address onto the stack and sets the instruction pointer (%eip) to
   1.513 +  // the entry point of the called routine.  The called routine then
   1.514 +  // PUSHes the calling routine's frame pointer (%ebp) onto the stack
   1.515 +  // before copying the stack pointer (%esp) to the frame pointer (%ebp).
   1.516 +  // Therefore, the calling procedure's frame pointer is always available
   1.517 +  // by dereferencing the called procedure's frame pointer, and the return
   1.518 +  // address is always available at the memory location immediately above
   1.519 +  // the address pointed to by the called procedure's frame pointer.  The
   1.520 +  // calling procedure's stack pointer (%esp) is 8 higher than the value
   1.521 +  // of the called procedure's frame pointer at the time the calling
   1.522 +  // procedure made the CALL: 4 bytes for the return address pushed by the
   1.523 +  // CALL itself, and 4 bytes for the callee's PUSH of the caller's frame
   1.524 +  // pointer.
   1.525 +  //
   1.526 +  // %eip_new = *(%ebp_old + 4)
   1.527 +  // %esp_new = %ebp_old + 8
   1.528 +  // %ebp_new = *(%ebp_old)
   1.529 +
   1.530 +  uint32_t caller_eip, caller_esp, caller_ebp;
   1.531 +
   1.532 +  if (memory_->GetMemoryAtAddress(last_ebp + 4, &caller_eip) &&
   1.533 +      memory_->GetMemoryAtAddress(last_ebp, &caller_ebp)) {
   1.534 +    caller_esp = last_ebp + 8;
   1.535 +    trust = StackFrame::FRAME_TRUST_FP;
   1.536 +  } else {
   1.537 +    // We couldn't read the memory %ebp refers to. It may be that %ebp
   1.538 +    // is pointing to non-stack memory. We'll scan the stack for a
   1.539 +    // return address. This can happen if last_frame is executing code
   1.540 +    // for a module for which we don't have symbols, and that module
   1.541 +    // is compiled without a frame pointer.
   1.542 +    if (!stack_scan_allowed
   1.543 +        || !ScanForReturnAddress(last_esp, &caller_esp, &caller_eip)) {
   1.544 +      // if we can't find an instruction pointer even with stack scanning,
   1.545 +      // give up.
   1.546 +      return NULL;
   1.547 +    }
   1.548 +
   1.549 +    // ScanForReturnAddress found a reasonable return address. Advance
   1.550 +    // %esp to the location above the one where the return address was
   1.551 +    // found. Assume that %ebp is unchanged.
   1.552 +    caller_esp += 4;
   1.553 +    caller_ebp = last_ebp;
   1.554 +
   1.555 +    trust = StackFrame::FRAME_TRUST_SCAN;
   1.556 +  }
   1.557 +
   1.558 +  // Create a new stack frame (ownership will be transferred to the caller)
   1.559 +  // and fill it in.
   1.560 +  StackFrameX86* frame = new StackFrameX86();
   1.561 +
   1.562 +  frame->trust = trust;
   1.563 +  frame->context = last_frame->context;
   1.564 +  frame->context.eip = caller_eip;
   1.565 +  frame->context.esp = caller_esp;
   1.566 +  frame->context.ebp = caller_ebp;
   1.567 +  frame->context_validity = StackFrameX86::CONTEXT_VALID_EIP |
   1.568 +                            StackFrameX86::CONTEXT_VALID_ESP |
   1.569 +                            StackFrameX86::CONTEXT_VALID_EBP;
   1.570 +
   1.571 +  return frame;
   1.572 +}
   1.573 +
   1.574 +StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack,
   1.575 +                                           bool stack_scan_allowed) {
   1.576 +  if (!memory_ || !stack) {
   1.577 +    BPLOG(ERROR) << "Can't get caller frame without memory or stack";
   1.578 +    return NULL;
   1.579 +  }
   1.580 +
   1.581 +  const vector<StackFrame*> &frames = *stack->frames();
   1.582 +  StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back());
   1.583 +  scoped_ptr<StackFrameX86> new_frame;
   1.584 +
   1.585 +  // If the resolver has Windows stack walking information, use that.
   1.586 +  WindowsFrameInfo* windows_frame_info
   1.587 +      = frame_symbolizer_->FindWindowsFrameInfo(last_frame);
   1.588 +  if (windows_frame_info)
   1.589 +    new_frame.reset(GetCallerByWindowsFrameInfo(frames, windows_frame_info,
   1.590 +                                                stack_scan_allowed));
   1.591 +
   1.592 +  // If the resolver has DWARF CFI information, use that.
   1.593 +  if (!new_frame.get()) {
   1.594 +    CFIFrameInfo* cfi_frame_info =
   1.595 +        frame_symbolizer_->FindCFIFrameInfo(last_frame);
   1.596 +    if (cfi_frame_info)
   1.597 +      new_frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info));
   1.598 +  }
   1.599 +
   1.600 +  // Otherwise, hope that the program was using a traditional frame structure.
   1.601 +  if (!new_frame.get())
   1.602 +    new_frame.reset(GetCallerByEBPAtBase(frames, stack_scan_allowed));
   1.603 +
   1.604 +  // If nothing worked, tell the caller.
   1.605 +  if (!new_frame.get())
   1.606 +    return NULL;
   1.607 +
   1.608 +  // Treat an instruction address of 0 as end-of-stack.
   1.609 +  if (new_frame->context.eip == 0)
   1.610 +    return NULL;
   1.611 +
   1.612 +  // If the new stack pointer is at a lower address than the old, then
   1.613 +  // that's clearly incorrect. Treat this as end-of-stack to enforce
   1.614 +  // progress and avoid infinite loops.
   1.615 +  if (new_frame->context.esp <= last_frame->context.esp)
   1.616 +    return NULL;
   1.617 +
   1.618 +  // new_frame->context.eip is the return address, which is the instruction
   1.619 +  // after the CALL that caused us to arrive at the callee. Set
   1.620 +  // new_frame->instruction to one less than that, so it points within the
   1.621 +  // CALL instruction. See StackFrame::instruction for details, and
   1.622 +  // StackFrameAMD64::ReturnAddress.
   1.623 +  new_frame->instruction = new_frame->context.eip - 1;
   1.624 +
   1.625 +  return new_frame.release();
   1.626 +}
   1.627 +
   1.628 +}  // namespace google_breakpad

mercurial