/ src / processor / stackwalker_amd64_unittest.cc
stackwalker_amd64_unittest.cc
  1  // Copyright 2010 Google LLC
  2  //
  3  // Redistribution and use in source and binary forms, with or without
  4  // modification, are permitted provided that the following conditions are
  5  // met:
  6  //
  7  //     * Redistributions of source code must retain the above copyright
  8  // notice, this list of conditions and the following disclaimer.
  9  //     * Redistributions in binary form must reproduce the above
 10  // copyright notice, this list of conditions and the following disclaimer
 11  // in the documentation and/or other materials provided with the
 12  // distribution.
 13  //     * Neither the name of Google LLC nor the names of its
 14  // contributors may be used to endorse or promote products derived from
 15  // this software without specific prior written permission.
 16  //
 17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 21  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 22  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 23  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 24  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 25  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28  
 29  // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
 30  
 31  // stackwalker_amd64_unittest.cc: Unit tests for StackwalkerAMD64 class.
 32  
 33  #ifdef HAVE_CONFIG_H
 34  #include <config.h>  // Must come first
 35  #endif
 36  
 37  #include <string.h>
 38  #include <string>
 39  #include <vector>
 40  
 41  #include "breakpad_googletest_includes.h"
 42  #include "common/test_assembler.h"
 43  #include "common/using_std_string.h"
 44  #include "google_breakpad/common/minidump_format.h"
 45  #include "google_breakpad/processor/basic_source_line_resolver.h"
 46  #include "google_breakpad/processor/call_stack.h"
 47  #include "google_breakpad/processor/code_module.h"
 48  #include "google_breakpad/processor/source_line_resolver_interface.h"
 49  #include "google_breakpad/processor/stack_frame_cpu.h"
 50  #include "processor/stackwalker_unittest_utils.h"
 51  #include "processor/stackwalker_amd64.h"
 52  
 53  using google_breakpad::BasicSourceLineResolver;
 54  using google_breakpad::CallStack;
 55  using google_breakpad::CodeModule;
 56  using google_breakpad::StackFrameSymbolizer;
 57  using google_breakpad::StackFrame;
 58  using google_breakpad::StackFrameAMD64;
 59  using google_breakpad::Stackwalker;
 60  using google_breakpad::StackwalkerAMD64;
 61  using google_breakpad::SystemInfo;
 62  using google_breakpad::test_assembler::kLittleEndian;
 63  using google_breakpad::test_assembler::Label;
 64  using google_breakpad::test_assembler::Section;
 65  using std::vector;
 66  using testing::_;
 67  using testing::AnyNumber;
 68  using testing::DoAll;
 69  using testing::Return;
 70  using testing::SetArgumentPointee;
 71  using testing::Test;
 72  
 73  class StackwalkerAMD64Fixture {
 74   public:
 75    StackwalkerAMD64Fixture()
 76      : stack_section(kLittleEndian),
 77        // Give the two modules reasonable standard locations and names
 78        // for tests to play with.
 79        module1(0x00007400c0000000ULL, 0x10000, "module1", "version1"),
 80        module2(0x00007500b0000000ULL, 0x10000, "module2", "version2") {
 81      // Identify the system as a Linux system.
 82      system_info.os = "Linux";
 83      system_info.os_short = "linux";
 84      system_info.os_version = "Horrendous Hippo";
 85      system_info.cpu = "x86";
 86      system_info.cpu_info = "";
 87  
 88      // Put distinctive values in the raw CPU context.
 89      BrandContext(&raw_context);
 90  
 91      // Create some modules with some stock debugging information.
 92      modules.Add(&module1);
 93      modules.Add(&module2);
 94  
 95      // By default, none of the modules have symbol info; call
 96      // SetModuleSymbols to override this.
 97      EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _, _))
 98        .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
 99  
100      // Avoid GMOCK WARNING "Uninteresting mock function call - returning
101      // directly" for FreeSymbolData().
102      EXPECT_CALL(supplier, FreeSymbolData(_)).Times(AnyNumber());
103  
104      // Reset max_frames_scanned since it's static.
105      Stackwalker::set_max_frames_scanned(1024);
106    }
107  
108    // Set the Breakpad symbol information that supplier should return for
109    // MODULE to INFO.
110    void SetModuleSymbols(MockCodeModule* module, const string& info) {
111      size_t buffer_size;
112      char *buffer = supplier.CopySymbolDataAndOwnTheCopy(info, &buffer_size);
113      EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _, _))
114        .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
115                              SetArgumentPointee<4>(buffer_size),
116                              Return(MockSymbolSupplier::FOUND)));
117    }
118  
119    // Populate stack_region with the contents of stack_section. Use
120    // stack_section.start() as the region's starting address.
121    void RegionFromSection() {
122      string contents;
123      ASSERT_TRUE(stack_section.GetContents(&contents));
124      stack_region.Init(stack_section.start().Value(), contents);
125    }
126  
127    // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
128    void BrandContext(MDRawContextAMD64 *raw_context) {
129      uint8_t x = 173;
130      for (size_t i = 0; i < sizeof(*raw_context); i++)
131        reinterpret_cast<uint8_t*>(raw_context)[i] = (x += 17);
132    }
133  
134    SystemInfo system_info;
135    MDRawContextAMD64 raw_context;
136    Section stack_section;
137    MockMemoryRegion stack_region;
138    MockCodeModule module1;
139    MockCodeModule module2;
140    MockCodeModules modules;
141    MockSymbolSupplier supplier;
142    BasicSourceLineResolver resolver;
143    CallStack call_stack;
144    const vector<StackFrame*>* frames;
145  };
146  
147  class GetContextFrame: public StackwalkerAMD64Fixture, public Test { };
148  
149  class SanityCheck: public StackwalkerAMD64Fixture, public Test { };
150  
151  TEST_F(SanityCheck, NoResolver) {
152    // There should be no references to the stack in this walk: we don't
153    // provide any call frame information, so trying to reconstruct the
154    // context frame's caller should fail. So there's no need for us to
155    // provide stack contents.
156    raw_context.rip = 0x00007400c0000200ULL;
157    raw_context.rbp = 0x8000000080000000ULL;
158  
159    StackFrameSymbolizer frame_symbolizer(NULL, NULL);
160    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
161                            &frame_symbolizer);
162    // This should succeed even without a resolver or supplier.
163    vector<const CodeModule*> modules_without_symbols;
164    vector<const CodeModule*> modules_with_corrupt_symbols;
165    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
166                            &modules_with_corrupt_symbols));
167    ASSERT_EQ(1U, modules_without_symbols.size());
168    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
169    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
170    frames = call_stack.frames();
171    ASSERT_GE(1U, frames->size());
172    StackFrameAMD64 *frame = static_cast<StackFrameAMD64*>(frames->at(0));
173    // Check that the values from the original raw context made it
174    // through to the context in the stack frame.
175    EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
176  }
177  
178  TEST_F(GetContextFrame, Simple) {
179    // There should be no references to the stack in this walk: we don't
180    // provide any call frame information, so trying to reconstruct the
181    // context frame's caller should fail. So there's no need for us to
182    // provide stack contents.
183    raw_context.rip = 0x00007400c0000200ULL;
184    raw_context.rbp = 0x8000000080000000ULL;
185  
186    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
187    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
188                            &frame_symbolizer);
189    vector<const CodeModule*> modules_without_symbols;
190    vector<const CodeModule*> modules_with_corrupt_symbols;
191    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
192                            &modules_with_corrupt_symbols));
193    ASSERT_EQ(1U, modules_without_symbols.size());
194    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
195    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
196    frames = call_stack.frames();
197    ASSERT_GE(1U, frames->size());
198    StackFrameAMD64 *frame = static_cast<StackFrameAMD64*>(frames->at(0));
199    // Check that the values from the original raw context made it
200    // through to the context in the stack frame.
201    EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
202  }
203  
204  // The stackwalker should be able to produce the context frame even
205  // without stack memory present.
206  TEST_F(GetContextFrame, NoStackMemory) {
207    raw_context.rip = 0x00007400c0000200ULL;
208    raw_context.rbp = 0x8000000080000000ULL;
209  
210    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
211    StackwalkerAMD64 walker(&system_info, &raw_context, NULL, &modules,
212                            &frame_symbolizer);
213    vector<const CodeModule*> modules_without_symbols;
214    vector<const CodeModule*> modules_with_corrupt_symbols;
215    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
216                            &modules_with_corrupt_symbols));
217    ASSERT_EQ(1U, modules_without_symbols.size());
218    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
219    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
220    frames = call_stack.frames();
221    ASSERT_GE(1U, frames->size());
222    StackFrameAMD64 *frame = static_cast<StackFrameAMD64*>(frames->at(0));
223    // Check that the values from the original raw context made it
224    // through to the context in the stack frame.
225    EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
226  }
227  
228  class GetCallerFrame: public StackwalkerAMD64Fixture, public Test { };
229  
230  TEST_F(GetCallerFrame, ScanWithoutSymbols) {
231    // When the stack walker resorts to scanning the stack,
232    // only addresses located within loaded modules are
233    // considered valid return addresses.
234    // Force scanning through three frames to ensure that the
235    // stack pointer is set properly in scan-recovered frames.
236    stack_section.start() = 0x8000000080000000ULL;
237    uint64_t return_address1 = 0x00007500b0000100ULL;
238    uint64_t return_address2 = 0x00007500b0000900ULL;
239    Label frame1_sp, frame2_sp, frame1_rbp;
240    stack_section
241      // frame 0
242      .Append(16, 0)                      // space
243  
244      .D64(0x00007400b0000000ULL)         // junk that's not
245      .D64(0x00007500d0000000ULL)         // a return address
246  
247      .D64(return_address1)               // actual return address
248      // frame 1
249      .Mark(&frame1_sp)
250      .Append(16, 0)                      // space
251  
252      .D64(0x00007400b0000000ULL)         // more junk
253      .D64(0x00007500d0000000ULL)
254  
255      .Mark(&frame1_rbp)
256      .D64(stack_section.start())         // This is in the right place to be
257                                          // a saved rbp, but it's bogus, so
258                                          // we shouldn't report it.
259  
260      .D64(return_address2)               // actual return address
261      // frame 2
262      .Mark(&frame2_sp)
263      .Append(32, 0);                     // end of stack
264  
265    RegionFromSection();
266  
267    raw_context.rip = 0x00007400c0000200ULL;
268    raw_context.rbp = frame1_rbp.Value();
269    raw_context.rsp = stack_section.start().Value();
270  
271    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
272    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
273                            &frame_symbolizer);
274    vector<const CodeModule*> modules_without_symbols;
275    vector<const CodeModule*> modules_with_corrupt_symbols;
276    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
277                            &modules_with_corrupt_symbols));
278    ASSERT_EQ(2U, modules_without_symbols.size());
279    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
280    ASSERT_EQ("module2", modules_without_symbols[1]->debug_file());
281    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
282    frames = call_stack.frames();
283    ASSERT_EQ(3U, frames->size());
284  
285    StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64*>(frames->at(0));
286    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
287    ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
288    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
289  
290    StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64*>(frames->at(1));
291    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
292    ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
293               StackFrameAMD64::CONTEXT_VALID_RSP |
294               StackFrameAMD64::CONTEXT_VALID_RBP),
295              frame1->context_validity);
296    EXPECT_EQ(return_address1, frame1->context.rip);
297    EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
298    EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
299  
300    StackFrameAMD64 *frame2 = static_cast<StackFrameAMD64*>(frames->at(2));
301    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame2->trust);
302    ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
303               StackFrameAMD64::CONTEXT_VALID_RSP),
304              frame2->context_validity);
305    EXPECT_EQ(return_address2, frame2->context.rip);
306    EXPECT_EQ(frame2_sp.Value(), frame2->context.rsp);
307  }
308  
309  TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
310    // During stack scanning, if a potential return address
311    // is located within a loaded module that has symbols,
312    // it is only considered a valid return address if it
313    // lies within a function's bounds.
314    stack_section.start() = 0x8000000080000000ULL;
315    uint64_t return_address = 0x00007500b0000110ULL;
316    Label frame1_sp, frame1_rbp;
317  
318    stack_section
319      // frame 0
320      .Append(16, 0)                      // space
321  
322      .D64(0x00007400b0000000ULL)         // junk that's not
323      .D64(0x00007500b0000000ULL)         // a return address
324  
325      .D64(0x00007400c0001000ULL)         // a couple of plausible addresses
326      .D64(0x00007500b000aaaaULL)         // that are not within functions
327  
328      .D64(return_address)                // actual return address
329      // frame 1
330      .Mark(&frame1_sp)
331      .Append(32, 0)                      // end of stack
332      .Mark(&frame1_rbp);
333    RegionFromSection();
334  
335    raw_context.rip = 0x00007400c0000200ULL;
336    raw_context.rbp = frame1_rbp.Value();
337    raw_context.rsp = stack_section.start().Value();
338  
339    SetModuleSymbols(&module1,
340                     // The youngest frame's function.
341                     "FUNC 100 400 10 platypus\n");
342    SetModuleSymbols(&module2,
343                     // The calling frame's function.
344                     "FUNC 100 400 10 echidna\n");
345  
346    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
347    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
348                            &frame_symbolizer);
349    vector<const CodeModule*> modules_without_symbols;
350    vector<const CodeModule*> modules_with_corrupt_symbols;
351    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
352                            &modules_with_corrupt_symbols));
353    ASSERT_EQ(0U, modules_without_symbols.size());
354    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
355    frames = call_stack.frames();
356    ASSERT_EQ(2U, frames->size());
357  
358    StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64*>(frames->at(0));
359    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
360    ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
361    EXPECT_EQ("platypus", frame0->function_name);
362    EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base);
363  
364    StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64*>(frames->at(1));
365    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
366    ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
367               StackFrameAMD64::CONTEXT_VALID_RSP |
368               StackFrameAMD64::CONTEXT_VALID_RBP),
369              frame1->context_validity);
370    EXPECT_EQ(return_address, frame1->context.rip);
371    EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
372    EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
373    EXPECT_EQ("echidna", frame1->function_name);
374    EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base);
375  }
376  
377  // StackwalkerAMD64::GetCallerByFramePointerRecovery should never return an
378  // instruction pointer of 0 because IP of 0 is an end of stack marker and the
379  // stack walk may be terminated prematurely.  Instead it should return NULL
380  // so that the stack walking code can proceed to stack scanning.
381  TEST_F(GetCallerFrame, GetCallerByFramePointerRecovery) {
382    MockCodeModule user32_dll(0x00007ff9cb8a0000ULL, 0x14E000, "user32.dll",
383                              "version1");
384    SetModuleSymbols(&user32_dll,  // user32.dll
385                     "PUBLIC fa60 0 DispatchMessageWorker\n"
386                     "PUBLIC fee0 0 UserCallWinProcCheckWow\n"
387                     "PUBLIC 1cdb0 0 _fnHkINLPMSG\n"
388                     "STACK CFI INIT fa60 340 .cfa: $rsp .ra: .cfa 8 - ^\n"
389                     "STACK CFI fa60 .cfa: $rsp 128 +\n"
390                     "STACK CFI INIT fee0 49f .cfa: $rsp .ra: .cfa 8 - ^\n"
391                     "STACK CFI fee0 .cfa: $rsp 240 +\n"
392                     "STACK CFI INIT 1cdb0 9f .cfa: $rsp .ra: .cfa 8 - ^\n"
393                     "STACK CFI 1cdb0 .cfa: $rsp 80 +\n");
394  
395    // Create some modules with some stock debugging information.
396    MockCodeModules local_modules;
397    local_modules.Add(&user32_dll);
398  
399    Label frame0_rsp;
400    Label frame0_rbp;
401    Label frame1_rsp;
402    Label frame2_rsp;
403  
404    stack_section.start() = 0x00000099abf0f238ULL;
405    stack_section
406      .Mark(&frame0_rsp)
407      .D64(0x00007ff9cb8b00dcULL)
408      .Mark(&frame1_rsp)
409      .D64(0x0000000000000000ULL)
410      .D64(0x0000000000000001ULL)
411      .D64(0x00000099abf0f308ULL)
412      .D64(0x00007ff9cb8bce3aULL)  // Stack residue from execution of
413                                   // user32!_fnHkINLPMSG+0x8a
414      .D64(0x000000000000c2e0ULL)
415      .D64(0x00000099abf0f328ULL)
416      .D64(0x0000000100000001ULL)
417      .D64(0x0000000000000000ULL)
418      .D64(0x0000000000000000ULL)
419      .D64(0x0000000000000000ULL)
420      .D64(0x0000000000000000ULL)
421      .D64(0x0000000000000000ULL)
422      .D64(0x0000000000000000ULL)
423      .D64(0x00007ff9ccad53e4ULL)
424      .D64(0x0000000000000048ULL)
425      .D64(0x0000000000000001ULL)
426      .D64(0x00000099abf0f5e0ULL)
427      .D64(0x00000099b61f7388ULL)
428      .D64(0x0000000000000030ULL)
429      .D64(0xffffff66540f0a1fULL)
430      .D64(0xffffff6649e08c77ULL)
431      .D64(0x00007ff9cb8affb4ULL)  // Return address in
432                                   // user32!UserCallWinProcCheckWow+0xd4
433      .D64(0x0000000000000000ULL)
434      .D64(0x00000099abf0f368ULL)
435      .D64(0x0000000000000000ULL)
436      .D64(0x0000000000000000ULL)
437      .D64(0x0000000000000000ULL)
438      .D64(0x00000099a8150fd8ULL)
439      .D64(0x00000099abf0f3e8ULL)
440      .D64(0x00007ff9cb8afc07ULL)  // Return address in
441                                   // user32!DispatchMessageWorker+0x1a7
442      .Mark(&frame2_rsp)
443      .Append(256, 0)
444      .Mark(&frame0_rbp)           // The following are expected by
445                                   // GetCallerByFramePointerRecovery.
446      .D64(0xfffffffffffffffeULL)  // %caller_rbp = *(%callee_rbp)
447      .D64(0x0000000000000000ULL)  // %caller_rip = *(%callee_rbp + 8)
448      .D64(0x00000099a3e31040ULL)  // %caller_rsp = *(%callee_rbp + 16)
449      .Append(256, 0);
450  
451    RegionFromSection();
452    raw_context.rip = 0x00000099a8150fd8ULL;  // IP in context frame is guarbage
453    raw_context.rsp = frame0_rsp.Value();
454    raw_context.rbp = frame0_rbp.Value();
455  
456    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
457    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region,
458                            &local_modules, &frame_symbolizer);
459    vector<const CodeModule*> modules_without_symbols;
460    vector<const CodeModule*> modules_with_corrupt_symbols;
461    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
462                            &modules_with_corrupt_symbols));
463    ASSERT_EQ(0U, modules_without_symbols.size());
464    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
465    frames = call_stack.frames();
466  
467    ASSERT_EQ(3U, frames->size());
468  
469    {  // To avoid reusing locals by mistake
470      StackFrameAMD64 *frame = static_cast<StackFrameAMD64*>(frames->at(0));
471      EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame->trust);
472      ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame->context_validity);
473      EXPECT_EQ("", frame->function_name);
474      EXPECT_EQ(0x00000099a8150fd8ULL, frame->instruction);
475      EXPECT_EQ(0x00000099a8150fd8ULL, frame->context.rip);
476      EXPECT_EQ(frame0_rsp.Value(), frame->context.rsp);
477      EXPECT_EQ(frame0_rbp.Value(), frame->context.rbp);
478    }
479  
480    {  // To avoid reusing locals by mistake
481      StackFrameAMD64 *frame = static_cast<StackFrameAMD64*>(frames->at(1));
482      EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame->trust);
483      ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
484                 StackFrameAMD64::CONTEXT_VALID_RSP |
485                 StackFrameAMD64::CONTEXT_VALID_RBP),
486                frame->context_validity);
487      EXPECT_EQ("UserCallWinProcCheckWow", frame->function_name);
488      EXPECT_EQ(140710838468828ULL, frame->instruction + 1);
489      EXPECT_EQ(140710838468828ULL, frame->context.rip);
490      EXPECT_EQ(frame1_rsp.Value(), frame->context.rsp);
491      EXPECT_EQ(&user32_dll, frame->module);
492    }
493  
494    {  // To avoid reusing locals by mistake
495      StackFrameAMD64 *frame = static_cast<StackFrameAMD64*>(frames->at(2));
496      EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame->trust);
497      ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
498                 StackFrameAMD64::CONTEXT_VALID_RSP |
499                 StackFrameAMD64::CONTEXT_VALID_RBP),
500                frame->context_validity);
501      EXPECT_EQ("DispatchMessageWorker", frame->function_name);
502      EXPECT_EQ(140710838467591ULL, frame->instruction + 1);
503      EXPECT_EQ(140710838467591ULL, frame->context.rip);
504      EXPECT_EQ(frame2_rsp.Value(), frame->context.rsp);
505      EXPECT_EQ(&user32_dll, frame->module);
506    }
507  }
508  
509  // Don't use frame pointer recovery if %rbp is not 8-byte aligned, which
510  // indicates that it's not being used as a frame pointer.
511  TEST_F(GetCallerFrame, FramePointerNotAligned) {
512    stack_section.start() = 0x8000000080000000ULL;
513    uint64_t return_address1 = 0x00007500b0000100ULL;
514    Label frame0_rbp, not_frame1_rbp, frame1_sp;
515    stack_section
516      // frame 0
517      .Align(8, 0)
518      .Append(2, 0)                       // mis-align the frame pointer
519      .Mark(&frame0_rbp)
520      .D64(not_frame1_rbp)                // not the previous frame pointer
521      .D64(0x00007500b0000a00ULL)         // plausible but wrong return address
522      .Align(8, 0)
523      .D64(return_address1)               // return address
524      // frame 1
525      .Mark(&frame1_sp)
526      .Mark(&not_frame1_rbp)
527      .Append(32, 0);                     // end of stack
528  
529  
530    RegionFromSection();
531  
532    raw_context.rip = 0x00007400c0000200ULL;
533    raw_context.rbp = frame0_rbp.Value();
534    raw_context.rsp = stack_section.start().Value();
535  
536    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
537    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
538                            &frame_symbolizer);
539    vector<const CodeModule*> modules_without_symbols;
540    vector<const CodeModule*> modules_with_corrupt_symbols;
541    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
542                            &modules_with_corrupt_symbols));
543    frames = call_stack.frames();
544    ASSERT_EQ(2U, frames->size());
545  
546    StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64*>(frames->at(0));
547    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
548    ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
549    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
550  
551    StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64*>(frames->at(1));
552    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
553    ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
554               StackFrameAMD64::CONTEXT_VALID_RSP),
555              frame1->context_validity);
556    EXPECT_EQ(return_address1, frame1->context.rip);
557    EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
558  }
559  
560  // Don't use frame pointer recovery if the recovered %rip is not
561  // a canonical x86-64 address.
562  TEST_F(GetCallerFrame, NonCanonicalInstructionPointerFromFramePointer) {
563    stack_section.start() = 0x8000000080000000ULL;
564    uint64_t return_address1 = 0x00007500b0000100ULL;
565    Label frame0_rbp, frame1_sp, not_frame1_bp;
566    stack_section
567      // frame 0
568      .Align(8, 0)
569      .Mark(&frame0_rbp)
570      .D64(not_frame1_bp)                 // some junk on the stack
571      .D64(0xDADADADADADADADA)            // not the return address
572      .D64(return_address1)               // return address
573      // frame 1
574      .Mark(&frame1_sp)
575      .Append(16, 0)
576      .Mark(&not_frame1_bp)
577      .Append(32, 0);                     // end of stack
578  
579  
580    RegionFromSection();
581  
582    raw_context.rip = 0x00007400c0000200ULL;
583    raw_context.rbp = frame0_rbp.Value();
584    raw_context.rsp = stack_section.start().Value();
585  
586    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
587    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
588                            &frame_symbolizer);
589    vector<const CodeModule*> modules_without_symbols;
590    vector<const CodeModule*> modules_with_corrupt_symbols;
591    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
592                            &modules_with_corrupt_symbols));
593    frames = call_stack.frames();
594    ASSERT_EQ(2U, frames->size());
595  
596    StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64*>(frames->at(0));
597    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
598    ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
599    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
600  
601    StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64*>(frames->at(1));
602    EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
603    ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
604               StackFrameAMD64::CONTEXT_VALID_RSP),
605              frame1->context_validity);
606    EXPECT_EQ(return_address1, frame1->context.rip);
607    EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
608  }
609  
610  // Test that set_max_frames_scanned prevents using stack scanning
611  // to find caller frames.
612  TEST_F(GetCallerFrame, ScanningNotAllowed) {
613    // When the stack walker resorts to scanning the stack,
614    // only addresses located within loaded modules are
615    // considered valid return addresses.
616    stack_section.start() = 0x8000000080000000ULL;
617    uint64_t return_address1 = 0x00007500b0000100ULL;
618    uint64_t return_address2 = 0x00007500b0000900ULL;
619    Label frame1_sp, frame2_sp, frame1_rbp;
620    stack_section
621      // frame 0
622      .Append(16, 0)                      // space
623  
624      .D64(0x00007400b0000000ULL)         // junk that's not
625      .D64(0x00007500d0000000ULL)         // a return address
626  
627      .D64(return_address1)               // actual return address
628      // frame 1
629      .Mark(&frame1_sp)
630      .Append(16, 0)                      // space
631  
632      .D64(0x00007400b0000000ULL)         // more junk
633      .D64(0x00007500d0000000ULL)
634  
635      .Mark(&frame1_rbp)
636      .D64(stack_section.start())         // This is in the right place to be
637                                          // a saved rbp, but it's bogus, so
638                                          // we shouldn't report it.
639  
640      .D64(return_address2)               // actual return address
641      // frame 2
642      .Mark(&frame2_sp)
643      .Append(32, 0);                     // end of stack
644  
645    RegionFromSection();
646  
647    raw_context.rip = 0x00007400c0000200ULL;
648    raw_context.rbp = frame1_rbp.Value();
649    raw_context.rsp = stack_section.start().Value();
650  
651    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
652    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
653                            &frame_symbolizer);
654    Stackwalker::set_max_frames_scanned(0);
655  
656    vector<const CodeModule*> modules_without_symbols;
657    vector<const CodeModule*> modules_with_corrupt_symbols;
658    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
659                            &modules_with_corrupt_symbols));
660    ASSERT_EQ(1U, modules_without_symbols.size());
661    ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
662    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
663    frames = call_stack.frames();
664    ASSERT_EQ(1U, frames->size());
665  
666    StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64*>(frames->at(0));
667    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
668    ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
669    EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
670  }
671  
672  TEST_F(GetCallerFrame, CallerPushedRBP) {
673    // Functions typically push their %rbp upon entry and set %rbp pointing
674    // there.  If stackwalking finds a plausible address for the next frame's
675    // %rbp directly below the return address, assume that it is indeed the
676    // next frame's %rbp.
677    stack_section.start() = 0x8000000080000000ULL;
678    uint64_t return_address = 0x00007500b0000110ULL;
679    Label frame0_rbp, frame1_sp, frame1_rbp;
680  
681    stack_section
682      // frame 0
683      .Append(16, 0)                      // space
684  
685      .D64(0x00007400b0000000ULL)         // junk that's not
686      .D64(0x00007500b0000000ULL)         // a return address
687  
688      .D64(0x00007400c0001000ULL)         // a couple of plausible addresses
689      .D64(0x00007500b000aaaaULL)         // that are not within functions
690  
691      .Mark(&frame0_rbp)
692      .D64(frame1_rbp)                    // caller-pushed %rbp
693      .D64(return_address)                // actual return address
694      // frame 1
695      .Mark(&frame1_sp)
696      .Append(32, 0)                      // body of frame1
697      .Mark(&frame1_rbp)                  // end of stack
698      .D64(0);
699    RegionFromSection();
700  
701    raw_context.rip = 0x00007400c0000200ULL;
702    raw_context.rbp = frame0_rbp.Value();
703    raw_context.rsp = stack_section.start().Value();
704  
705    SetModuleSymbols(&module1,
706                     // The youngest frame's function.
707                     "FUNC 100 400 10 sasquatch\n");
708    SetModuleSymbols(&module2,
709                     // The calling frame's function.
710                     "FUNC 100 400 10 yeti\n");
711  
712    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
713    StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
714                            &frame_symbolizer);
715    vector<const CodeModule*> modules_without_symbols;
716    vector<const CodeModule*> modules_with_corrupt_symbols;
717    ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
718                            &modules_with_corrupt_symbols));
719    ASSERT_EQ(0U, modules_without_symbols.size());
720    ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
721    frames = call_stack.frames();
722    ASSERT_EQ(2U, frames->size());
723  
724    StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64*>(frames->at(0));
725    EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
726    ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
727    EXPECT_EQ(frame0_rbp.Value(), frame0->context.rbp);
728    EXPECT_EQ("sasquatch", frame0->function_name);
729    EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base);
730  
731    StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64*>(frames->at(1));
732    EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
733    ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
734               StackFrameAMD64::CONTEXT_VALID_RSP |
735               StackFrameAMD64::CONTEXT_VALID_RBP),
736              frame1->context_validity);
737    EXPECT_EQ(return_address, frame1->context.rip);
738    EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
739    EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
740    EXPECT_EQ("yeti", frame1->function_name);
741    EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base);
742  }
743  
744  struct CFIFixture: public StackwalkerAMD64Fixture {
745    CFIFixture() {
746      // Provide a bunch of STACK CFI records; we'll walk to the caller
747      // from every point in this series, expecting to find the same set
748      // of register values.
749      SetModuleSymbols(&module1,
750                       // The youngest frame's function.
751                       "FUNC 4000 1000 10 enchiridion\n"
752                       // Initially, just a return address.
753                       "STACK CFI INIT 4000 100 .cfa: $rsp 8 + .ra: .cfa 8 - ^\n"
754                       // Push %rbx.
755                       "STACK CFI 4001 .cfa: $rsp 16 + $rbx: .cfa 16 - ^\n"
756                       // Save %r12 in %rbx.  Weird, but permitted.
757                       "STACK CFI 4002 $r12: $rbx\n"
758                       // Allocate frame space, and save %r13.
759                       "STACK CFI 4003 .cfa: $rsp 40 + $r13: .cfa 32 - ^\n"
760                       // Put the return address in %r13.
761                       "STACK CFI 4005 .ra: $r13\n"
762                       // Save %rbp, and use it as a frame pointer.
763                       "STACK CFI 4006 .cfa: $rbp 16 + $rbp: .cfa 24 - ^\n"
764  
765                       // The calling function.
766                       "FUNC 5000 1000 10 epictetus\n"
767                       // Mark it as end of stack.
768                       "STACK CFI INIT 5000 1000 .cfa: $rsp .ra 0\n");
769  
770      // Provide some distinctive values for the caller's registers.
771      expected.rsp = 0x8000000080000000ULL;
772      expected.rip = 0x00007400c0005510ULL;
773      expected.rbp = 0x68995b1de4700266ULL;
774      expected.rbx = 0x5a5beeb38de23be8ULL;
775      expected.r12 = 0xed1b02e8cc0fc79cULL;
776      expected.r13 = 0x1d20ad8acacbe930ULL;
777      expected.r14 = 0xe94cffc2f7adaa28ULL;
778      expected.r15 = 0xb638d17d8da413b5ULL;
779  
780      // By default, registers are unchanged.
781      raw_context = expected;
782    }
783  
784    // Walk the stack, using stack_section as the contents of the stack
785    // and raw_context as the current register values. (Set
786    // raw_context.rsp to the stack's starting address.) Expect two
787    // stack frames; in the older frame, expect the callee-saves
788    // registers to have values matching those in 'expected'.
789    void CheckWalk() {
790      RegionFromSection();
791      raw_context.rsp = stack_section.start().Value();
792  
793      StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
794      StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
795                              &frame_symbolizer);
796      vector<const CodeModule*> modules_without_symbols;
797      vector<const CodeModule*> modules_with_corrupt_symbols;
798      ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
799                              &modules_with_corrupt_symbols));
800      ASSERT_EQ(0U, modules_without_symbols.size());
801      ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
802      frames = call_stack.frames();
803      ASSERT_EQ(2U, frames->size());
804  
805      StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64*>(frames->at(0));
806      EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
807      ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
808      EXPECT_EQ("enchiridion", frame0->function_name);
809      EXPECT_EQ(0x00007400c0004000ULL, frame0->function_base);
810  
811      StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64*>(frames->at(1));
812      EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
813      ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
814                 StackFrameAMD64::CONTEXT_VALID_RSP |
815                 StackFrameAMD64::CONTEXT_VALID_RBP |
816                 StackFrameAMD64::CONTEXT_VALID_RBX |
817                 StackFrameAMD64::CONTEXT_VALID_R12 |
818                 StackFrameAMD64::CONTEXT_VALID_R13 |
819                 StackFrameAMD64::CONTEXT_VALID_R14 |
820                 StackFrameAMD64::CONTEXT_VALID_R15),
821                frame1->context_validity);
822      EXPECT_EQ(expected.rip, frame1->context.rip);
823      EXPECT_EQ(expected.rsp, frame1->context.rsp);
824      EXPECT_EQ(expected.rbp, frame1->context.rbp);
825      EXPECT_EQ(expected.rbx, frame1->context.rbx);
826      EXPECT_EQ(expected.r12, frame1->context.r12);
827      EXPECT_EQ(expected.r13, frame1->context.r13);
828      EXPECT_EQ(expected.r14, frame1->context.r14);
829      EXPECT_EQ(expected.r15, frame1->context.r15);
830      EXPECT_EQ("epictetus", frame1->function_name);
831    }
832  
833    // The values we expect to find for the caller's registers.
834    MDRawContextAMD64 expected;
835  };
836  
837  class CFI: public CFIFixture, public Test { };
838  
839  TEST_F(CFI, At4000) {
840    Label frame1_rsp = expected.rsp;
841    stack_section
842      .D64(0x00007400c0005510ULL) // return address
843      .Mark(&frame1_rsp);         // This effectively sets stack_section.start().
844    raw_context.rip = 0x00007400c0004000ULL;
845    CheckWalk();
846  }
847  
848  TEST_F(CFI, At4001) {
849    Label frame1_rsp = expected.rsp;
850    stack_section
851      .D64(0x5a5beeb38de23be8ULL) // saved %rbx
852      .D64(0x00007400c0005510ULL) // return address
853      .Mark(&frame1_rsp);         // This effectively sets stack_section.start().
854    raw_context.rip = 0x00007400c0004001ULL;
855    raw_context.rbx = 0xbe0487d2f9eafe29ULL; // callee's (distinct) %rbx value
856    CheckWalk();
857  }
858  
859  TEST_F(CFI, At4002) {
860    Label frame1_rsp = expected.rsp;
861    stack_section
862      .D64(0x5a5beeb38de23be8ULL) // saved %rbx
863      .D64(0x00007400c0005510ULL) // return address
864      .Mark(&frame1_rsp);         // This effectively sets stack_section.start().
865    raw_context.rip = 0x00007400c0004002ULL;
866    raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
867    raw_context.r12 = 0xb0118de918a4bceaULL; // callee's (distinct) %r12 value
868    CheckWalk();
869  }
870  
871  TEST_F(CFI, At4003) {
872    Label frame1_rsp = expected.rsp;
873    stack_section
874      .D64(0x0e023828dffd4d81ULL) // garbage
875      .D64(0x1d20ad8acacbe930ULL) // saved %r13
876      .D64(0x319e68b49e3ace0fULL) // garbage
877      .D64(0x5a5beeb38de23be8ULL) // saved %rbx
878      .D64(0x00007400c0005510ULL) // return address
879      .Mark(&frame1_rsp);         // This effectively sets stack_section.start().
880    raw_context.rip = 0x00007400c0004003ULL;
881    raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
882    raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12
883    raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13
884    CheckWalk();
885  }
886  
887  // The results here should be the same as those at module offset 0x4003.
888  TEST_F(CFI, At4004) {
889    Label frame1_rsp = expected.rsp;
890    stack_section
891      .D64(0x0e023828dffd4d81ULL) // garbage
892      .D64(0x1d20ad8acacbe930ULL) // saved %r13
893      .D64(0x319e68b49e3ace0fULL) // garbage
894      .D64(0x5a5beeb38de23be8ULL) // saved %rbx
895      .D64(0x00007400c0005510ULL) // return address
896      .Mark(&frame1_rsp);         // This effectively sets stack_section.start().
897    raw_context.rip = 0x00007400c0004004ULL;
898    raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
899    raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12
900    raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13
901    CheckWalk();
902  }
903  
904  TEST_F(CFI, At4005) {
905    Label frame1_rsp = expected.rsp;
906    stack_section
907      .D64(0x4b516dd035745953ULL) // garbage
908      .D64(0x1d20ad8acacbe930ULL) // saved %r13
909      .D64(0xa6d445e16ae3d872ULL) // garbage
910      .D64(0x5a5beeb38de23be8ULL) // saved %rbx
911      .D64(0xaa95fa054aedfbaeULL) // garbage
912      .Mark(&frame1_rsp);         // This effectively sets stack_section.start().
913    raw_context.rip = 0x00007400c0004005ULL;
914    raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
915    raw_context.r12 = 0x46b1b8868891b34aULL; // callee's %r12
916    raw_context.r13 = 0x00007400c0005510ULL; // return address
917    CheckWalk();
918  }
919  
920  TEST_F(CFI, At4006) {
921    Label frame0_rbp;
922    Label frame1_rsp = expected.rsp;
923    stack_section
924      .D64(0x043c6dfceb91aa34ULL) // garbage
925      .D64(0x1d20ad8acacbe930ULL) // saved %r13
926      .D64(0x68995b1de4700266ULL) // saved %rbp
927      .Mark(&frame0_rbp)          // frame pointer points here
928      .D64(0x5a5beeb38de23be8ULL) // saved %rbx
929      .D64(0xf015ee516ad89eabULL) // garbage
930      .Mark(&frame1_rsp);         // This effectively sets stack_section.start().
931    raw_context.rip = 0x00007400c0004006ULL;
932    raw_context.rbp = frame0_rbp.Value();
933    raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
934    raw_context.r12 = 0x26e007b341acfebdULL; // callee's %r12
935    raw_context.r13 = 0x00007400c0005510ULL; // return address
936    CheckWalk();
937  }