Home | History | Annotate | Download | only in processor
      1 // Copyright (c) 2006, 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 
     30 // stackwalker_selftest.cc: Tests StackwalkerX86 or StackwalkerPPC using the
     31 // running process' stack as test data, if running on an x86 or ppc and
     32 // compiled with gcc.  This test is not enabled in the "make check" suite
     33 // by default, because certain optimizations interfere with its proper
     34 // operation.  To turn it on, configure with --enable-selftest.
     35 //
     36 // Optimizations that cause problems:
     37 //  - stack frame reuse.  The Recursor function here calls itself with
     38 //    |return Recursor|.  When the caller's frame is reused, it will cause
     39 //    CountCallerFrames to correctly return the same number of frames
     40 //    in both the caller and callee.  This is considered an unexpected
     41 //    condition in the test, which expects a callee to have one more
     42 //    caller frame in the stack than its caller.
     43 //  - frame pointer omission.  Even with a stackwalker that understands
     44 //    this optimization, the code to harness debug information currently
     45 //    only exists to retrieve it from minidumps, not the current process.
     46 //
     47 // This test can also serve as a developmental and debugging aid if
     48 // PRINT_STACKS is defined.
     49 //
     50 // Author: Mark Mentovai
     51 
     52 #include <assert.h>
     53 
     54 #include "processor/logging.h"
     55 
     56 #if defined(__i386) && !defined(__i386__)
     57 #define __i386__
     58 #endif
     59 #if defined(__sparc) && !defined(__sparc__)
     60 #define __sparc__
     61 #endif
     62 
     63 #if (defined(__SUNPRO_CC) || defined(__GNUC__)) && \
     64     (defined(__i386__) || defined(__ppc__) || defined(__sparc__))
     65 
     66 
     67 #include <stdio.h>
     68 
     69 #include "common/scoped_ptr.h"
     70 #include "google_breakpad/common/breakpad_types.h"
     71 #include "google_breakpad/common/minidump_format.h"
     72 #include "google_breakpad/processor/basic_source_line_resolver.h"
     73 #include "google_breakpad/processor/call_stack.h"
     74 #include "google_breakpad/processor/code_module.h"
     75 #include "google_breakpad/processor/memory_region.h"
     76 #include "google_breakpad/processor/stack_frame.h"
     77 #include "google_breakpad/processor/stack_frame_cpu.h"
     78 
     79 using google_breakpad::BasicSourceLineResolver;
     80 using google_breakpad::CallStack;
     81 using google_breakpad::CodeModule;
     82 using google_breakpad::MemoryRegion;
     83 using google_breakpad::scoped_ptr;
     84 using google_breakpad::StackFrame;
     85 using google_breakpad::StackFramePPC;
     86 using google_breakpad::StackFrameX86;
     87 using google_breakpad::StackFrameSPARC;
     88 
     89 #if defined(__i386__)
     90 #include "processor/stackwalker_x86.h"
     91 using google_breakpad::StackwalkerX86;
     92 #elif defined(__ppc__)
     93 #include "processor/stackwalker_ppc.h"
     94 using google_breakpad::StackwalkerPPC;
     95 #elif defined(__sparc__)
     96 #include "processor/stackwalker_sparc.h"
     97 using google_breakpad::StackwalkerSPARC;
     98 #endif  // __i386__ || __ppc__ || __sparc__
     99 
    100 #define RECURSION_DEPTH 100
    101 
    102 
    103 // A simple MemoryRegion subclass that provides direct access to this
    104 // process' memory space by pointer.
    105 class SelfMemoryRegion : public MemoryRegion {
    106  public:
    107   virtual uint64_t GetBase() const { return 0; }
    108   virtual uint32_t GetSize() const { return 0xffffffff; }
    109 
    110   bool GetMemoryAtAddress(uint64_t address, uint8_t*  value) const {
    111       return GetMemoryAtAddressInternal(address, value); }
    112   bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const {
    113       return GetMemoryAtAddressInternal(address, value); }
    114   bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const {
    115       return GetMemoryAtAddressInternal(address, value); }
    116   bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const {
    117       return GetMemoryAtAddressInternal(address, value); }
    118   void Print() const {
    119     assert(false);
    120   }
    121 
    122  private:
    123   template<typename T> bool GetMemoryAtAddressInternal(uint64_t address,
    124                                                        T*        value) {
    125     // Without knowing what addresses are actually mapped, just assume that
    126     // everything low is not mapped.  This helps the stackwalker catch the
    127     // end of a stack when it tries to dereference a null or low pointer
    128     // in an attempt to find the caller frame.  Other unmapped accesses will
    129     // cause the program to crash, but that would properly be a test failure.
    130     if (address < 0x100)
    131       return false;
    132 
    133     uint8_t* memory = 0;
    134     *value = *reinterpret_cast<const T*>(&memory[address]);
    135     return true;
    136   }
    137 };
    138 
    139 
    140 #if defined(__GNUC__)
    141 
    142 
    143 #if defined(__i386__)
    144 
    145 // GetEBP returns the current value of the %ebp register.  Because it's
    146 // implemented as a function, %ebp itself contains GetEBP's frame pointer
    147 // and not the caller's frame pointer.  Dereference %ebp to obtain the
    148 // caller's frame pointer, which the compiler-generated preamble stored
    149 // on the stack (provided frame pointers are not being omitted.)  Because
    150 // this function depends on the compiler-generated preamble, inlining is
    151 // disabled.
    152 static uint32_t GetEBP() __attribute__((noinline));
    153 static uint32_t GetEBP() {
    154   uint32_t ebp;
    155   __asm__ __volatile__(
    156     "movl (%%ebp), %0"
    157     : "=a" (ebp)
    158   );
    159   return ebp;
    160 }
    161 
    162 
    163 // The caller's %esp is 8 higher than the value of %ebp in this function,
    164 // assuming that it's not inlined and that the standard prolog is used.
    165 // The CALL instruction places a 4-byte return address on the stack above
    166 // the caller's %esp, and this function's prolog will save the caller's %ebp
    167 // on the stack as well, for another 4 bytes, before storing %esp in %ebp.
    168 static uint32_t GetESP() __attribute__((noinline));
    169 static uint32_t GetESP() {
    170   uint32_t ebp;
    171   __asm__ __volatile__(
    172     "movl %%ebp, %0"
    173     : "=a" (ebp)
    174   );
    175   return ebp + 8;
    176 }
    177 
    178 
    179 // GetEIP returns the instruction pointer identifying the next instruction
    180 // to execute after GetEIP returns.  It obtains this information from the
    181 // stack, where it was placed by the call instruction that called GetEIP.
    182 // This function depends on frame pointers not being omitted.  It is possible
    183 // to write a pure asm version of this routine that has no compiler-generated
    184 // preamble and uses %esp instead of %ebp; that would function in the
    185 // absence of frame pointers.  However, the simpler approach is used here
    186 // because GetEBP and stackwalking necessarily depends on access to frame
    187 // pointers.  Because this function depends on a call instruction and the
    188 // compiler-generated preamble, inlining is disabled.
    189 static uint32_t GetEIP() __attribute__((noinline));
    190 static uint32_t GetEIP() {
    191   uint32_t eip;
    192   __asm__ __volatile__(
    193     "movl 4(%%ebp), %0"
    194     : "=a" (eip)
    195   );
    196   return eip;
    197 }
    198 
    199 
    200 #elif defined(__ppc__)
    201 
    202 
    203 // GetSP returns the current value of the %r1 register, which by convention,
    204 // is the stack pointer on ppc.  Because it's implemented as a function,
    205 // %r1 itself contains GetSP's own stack pointer and not the caller's stack
    206 // pointer.  Dereference %r1 to obtain the caller's stack pointer, which the
    207 // compiler-generated prolog stored on the stack.  Because this function
    208 // depends on the compiler-generated prolog, inlining is disabled.
    209 static uint32_t GetSP() __attribute__((noinline));
    210 static uint32_t GetSP() {
    211   uint32_t sp;
    212   __asm__ __volatile__(
    213     "lwz %0, 0(r1)"
    214     : "=r" (sp)
    215   );
    216   return sp;
    217 }
    218 
    219 
    220 // GetPC returns the program counter identifying the next instruction to
    221 // execute after GetPC returns.  It obtains this information from the
    222 // link register, where it was placed by the branch instruction that called
    223 // GetPC.  Because this function depends on the caller's use of a branch
    224 // instruction, inlining is disabled.
    225 static uint32_t GetPC() __attribute__((noinline));
    226 static uint32_t GetPC() {
    227   uint32_t lr;
    228   __asm__ __volatile__(
    229     "mflr %0"
    230     : "=r" (lr)
    231   );
    232   return lr;
    233 }
    234 
    235 
    236 #elif defined(__sparc__)
    237 
    238 
    239 // GetSP returns the current value of the %sp/%o6/%g_r[14] register, which
    240 // by convention, is the stack pointer on sparc.  Because it's implemented
    241 // as a function, %sp itself contains GetSP's own stack pointer and not
    242 // the caller's stack pointer.  Dereference  to obtain the caller's stack
    243 // pointer, which the compiler-generated prolog stored on the stack.
    244 // Because this function depends on the compiler-generated prolog, inlining
    245 // is disabled.
    246 static uint32_t GetSP() __attribute__((noinline));
    247 static uint32_t GetSP() {
    248   uint32_t sp;
    249   __asm__ __volatile__(
    250     "mov %%fp, %0"
    251     : "=r" (sp)
    252   );
    253   return sp;
    254 }
    255 
    256 // GetFP returns the current value of the %fp register.  Because it's
    257 // implemented as a function, %fp itself contains GetFP's frame pointer
    258 // and not the caller's frame pointer.  Dereference %fp to obtain the
    259 // caller's frame pointer, which the compiler-generated preamble stored
    260 // on the stack (provided frame pointers are not being omitted.)  Because
    261 // this function depends on the compiler-generated preamble, inlining is
    262 // disabled.
    263 static uint32_t GetFP() __attribute__((noinline));
    264 static uint32_t GetFP() {
    265   uint32_t fp;
    266   __asm__ __volatile__(
    267     "ld [%%fp+56], %0"
    268     : "=r" (fp)
    269   );
    270   return fp;
    271 }
    272 
    273 // GetPC returns the program counter identifying the next instruction to
    274 // execute after GetPC returns.  It obtains this information from the
    275 // link register, where it was placed by the branch instruction that called
    276 // GetPC.  Because this function depends on the caller's use of a branch
    277 // instruction, inlining is disabled.
    278 static uint32_t GetPC() __attribute__((noinline));
    279 static uint32_t GetPC() {
    280   uint32_t pc;
    281   __asm__ __volatile__(
    282     "mov %%i7, %0"
    283     : "=r" (pc)
    284   );
    285   return pc + 8;
    286 }
    287 
    288 #endif  // __i386__ || __ppc__ || __sparc__
    289 
    290 #elif defined(__SUNPRO_CC)
    291 
    292 #if defined(__i386__)
    293 extern "C" {
    294 extern uint32_t GetEIP();
    295 extern uint32_t GetEBP();
    296 extern uint32_t GetESP();
    297 }
    298 #elif defined(__sparc__)
    299 extern "C" {
    300 extern uint32_t GetPC();
    301 extern uint32_t GetFP();
    302 extern uint32_t GetSP();
    303 }
    304 #endif // __i386__ || __sparc__
    305 
    306 #endif // __GNUC__ || __SUNPRO_CC
    307 
    308 // CountCallerFrames returns the number of stack frames beneath the function
    309 // that called CountCallerFrames.  Because this function's return value
    310 // is dependent on the size of the stack beneath it, inlining is disabled,
    311 // and any function that calls this should not be inlined either.
    312 #if defined(__GNUC__)
    313 static unsigned int CountCallerFrames() __attribute__((noinline));
    314 #elif defined(__SUNPRO_CC)
    315 static unsigned int CountCallerFrames();
    316 #endif
    317 static unsigned int CountCallerFrames() {
    318   SelfMemoryRegion memory;
    319   BasicSourceLineResolver resolver;
    320 
    321 #if defined(__i386__)
    322   MDRawContextX86 context = MDRawContextX86();
    323   context.eip = GetEIP();
    324   context.ebp = GetEBP();
    325   context.esp = GetESP();
    326 
    327   StackwalkerX86 stackwalker = StackwalkerX86(NULL, &context, &memory, NULL,
    328                                               NULL, &resolver);
    329 #elif defined(__ppc__)
    330   MDRawContextPPC context = MDRawContextPPC();
    331   context.srr0 = GetPC();
    332   context.gpr[1] = GetSP();
    333 
    334   StackwalkerPPC stackwalker = StackwalkerPPC(NULL, &context, &memory, NULL,
    335                                               NULL, &resolver);
    336 #elif defined(__sparc__)
    337   MDRawContextSPARC context = MDRawContextSPARC();
    338   context.pc = GetPC();
    339   context.g_r[14] = GetSP();
    340   context.g_r[30] = GetFP();
    341 
    342   StackwalkerSPARC stackwalker = StackwalkerSPARC(NULL, &context, &memory,
    343                                                   NULL, NULL, &resolver);
    344 #endif  // __i386__ || __ppc__ || __sparc__
    345 
    346   CallStack stack;
    347   vector<const CodeModule*> modules_without_symbols;
    348   stackwalker.Walk(&stack, &modules_without_symbols);
    349 
    350 #ifdef PRINT_STACKS
    351   printf("\n");
    352   for (unsigned int frame_index = 0;
    353       frame_index < stack.frames()->size();
    354       ++frame_index) {
    355     StackFrame *frame = stack.frames()->at(frame_index);
    356     printf("frame %-3d  instruction = 0x%08" PRIx64,
    357            frame_index, frame->instruction);
    358 #if defined(__i386__)
    359     StackFrameX86 *frame_x86 = reinterpret_cast<StackFrameX86*>(frame);
    360     printf("  esp = 0x%08x  ebp = 0x%08x\n",
    361            frame_x86->context.esp, frame_x86->context.ebp);
    362 #elif defined(__ppc__)
    363     StackFramePPC *frame_ppc = reinterpret_cast<StackFramePPC*>(frame);
    364     printf("  gpr[1] = 0x%08x\n", frame_ppc->context.gpr[1]);
    365 #elif defined(__sparc__)
    366     StackFrameSPARC *frame_sparc = reinterpret_cast<StackFrameSPARC*>(frame);
    367     printf("  sp = 0x%08x  fp = 0x%08x\n",
    368            frame_sparc->context.g_r[14], frame_sparc->context.g_r[30]);
    369 #endif  // __i386__ || __ppc__ || __sparc__
    370   }
    371 #endif  // PRINT_STACKS
    372 
    373   // Subtract 1 because the caller wants the number of frames beneath
    374   // itself.  Because the caller called us, subract two for our frame and its
    375   // frame, which are included in stack.size().
    376   return stack.frames()->size() - 2;
    377 }
    378 
    379 
    380 // Recursor verifies that the number stack frames beneath itself is one more
    381 // than the number of stack frames beneath its parent.  When depth frames
    382 // have been reached, Recursor stops checking and returns success.  If the
    383 // frame count check fails at any depth, Recursor will stop and return false.
    384 // Because this calls CountCallerFrames, inlining is disabled.
    385 #if defined(__GNUC__)
    386 static bool Recursor(unsigned int depth, unsigned int parent_callers)
    387     __attribute__((noinline));
    388 #elif defined(__SUNPRO_CC)
    389 static bool Recursor(unsigned int depth, unsigned int parent_callers);
    390 #endif
    391 static bool Recursor(unsigned int depth, unsigned int parent_callers) {
    392   unsigned int callers = CountCallerFrames();
    393   if (callers != parent_callers + 1)
    394     return false;
    395 
    396   if (depth)
    397     return Recursor(depth - 1, callers);
    398 
    399   // depth == 0
    400   return true;
    401 }
    402 
    403 
    404 // Because this calls CountCallerFrames, inlining is disabled - but because
    405 // it's main (and nobody calls it other than the entry point), it wouldn't
    406 // be inlined anyway.
    407 #if defined(__GNUC__)
    408 int main(int argc, char** argv) __attribute__((noinline));
    409 #elif defined(__SUNPRO_CC)
    410 int main(int argc, char** argv);
    411 #endif
    412 int main(int argc, char** argv) {
    413   BPLOG_INIT(&argc, &argv);
    414 
    415   return Recursor(RECURSION_DEPTH, CountCallerFrames()) ? 0 : 1;
    416 }
    417 
    418 
    419 #else
    420 // Not i386 or ppc or sparc?  We can only test stacks we know how to walk.
    421 
    422 
    423 int main(int argc, char **argv) {
    424   BPLOG_INIT(&argc, &argv);
    425 
    426   // "make check" interprets an exit status of 77 to mean that the test is
    427   // not supported.
    428   BPLOG(ERROR) << "Selftest not supported here";
    429   return 77;
    430 }
    431 
    432 
    433 #endif  // (__GNUC__ || __SUNPRO_CC) && (__i386__ || __ppc__ || __sparc__)
    434