PageRenderTime 59ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/thirdparty/breakpad/processor/stackwalker_x86_unittest.cc

http://github.com/tomahawk-player/tomahawk
C++ | 1246 lines | 973 code | 96 blank | 177 comment | 16 complexity | 30817944cd728fe20aee4051da486407 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, GPL-3.0, GPL-2.0
  1. // Copyright (c) 2010, Google Inc.
  2. // All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. //
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. // * Neither the name of Google Inc. nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
  30. // stackwalker_x86_unittest.cc: Unit tests for StackwalkerX86 class.
  31. #include <string>
  32. #include <vector>
  33. #include "breakpad_googletest_includes.h"
  34. #include "common/test_assembler.h"
  35. #include "google_breakpad/common/minidump_format.h"
  36. #include "google_breakpad/processor/basic_source_line_resolver.h"
  37. #include "google_breakpad/processor/call_stack.h"
  38. #include "google_breakpad/processor/source_line_resolver_interface.h"
  39. #include "google_breakpad/processor/stack_frame_cpu.h"
  40. #include "processor/stackwalker_unittest_utils.h"
  41. #include "processor/stackwalker_x86.h"
  42. #include "processor/windows_frame_info.h"
  43. using google_breakpad::BasicSourceLineResolver;
  44. using google_breakpad::CallStack;
  45. using google_breakpad::StackFrame;
  46. using google_breakpad::StackFrameX86;
  47. using google_breakpad::StackwalkerX86;
  48. using google_breakpad::SystemInfo;
  49. using google_breakpad::WindowsFrameInfo;
  50. using google_breakpad::test_assembler::kLittleEndian;
  51. using google_breakpad::test_assembler::Label;
  52. using google_breakpad::test_assembler::Section;
  53. using std::string;
  54. using std::vector;
  55. using testing::_;
  56. using testing::Return;
  57. using testing::SetArgumentPointee;
  58. using testing::Test;
  59. class StackwalkerX86Fixture {
  60. public:
  61. StackwalkerX86Fixture()
  62. : stack_section(kLittleEndian),
  63. // Give the two modules reasonable standard locations and names
  64. // for tests to play with.
  65. module1(0x40000000, 0x10000, "module1", "version1"),
  66. module2(0x50000000, 0x10000, "module2", "version2"),
  67. module3(0x771d0000, 0x180000, "module3", "version3"),
  68. module4(0x75f90000, 0x46000, "module4", "version4"),
  69. module5(0x75730000, 0x110000, "module5", "version5"),
  70. module6(0x647f0000, 0x1ba8000, "module6", "version6") {
  71. // Identify the system as a Linux system.
  72. system_info.os = "Linux";
  73. system_info.os_short = "linux";
  74. system_info.os_version = "Salacious Skink";
  75. system_info.cpu = "x86";
  76. system_info.cpu_info = "";
  77. // Put distinctive values in the raw CPU context.
  78. BrandContext(&raw_context);
  79. // Create some modules with some stock debugging information.
  80. modules.Add(&module1);
  81. modules.Add(&module2);
  82. modules.Add(&module3);
  83. modules.Add(&module4);
  84. modules.Add(&module5);
  85. modules.Add(&module6);
  86. // By default, none of the modules have symbol info; call
  87. // SetModuleSymbols to override this.
  88. EXPECT_CALL(supplier, GetCStringSymbolData(_, _, _, _))
  89. .WillRepeatedly(Return(MockSymbolSupplier::NOT_FOUND));
  90. }
  91. // Set the Breakpad symbol information that supplier should return for
  92. // MODULE to INFO.
  93. void SetModuleSymbols(MockCodeModule *module, const string &info) {
  94. unsigned int buffer_size = info.size() + 1;
  95. char *buffer = reinterpret_cast<char*>(operator new(buffer_size));
  96. strcpy(buffer, info.c_str());
  97. EXPECT_CALL(supplier, GetCStringSymbolData(module, &system_info, _, _))
  98. .WillRepeatedly(DoAll(SetArgumentPointee<3>(buffer),
  99. Return(MockSymbolSupplier::FOUND)));
  100. }
  101. // Populate stack_region with the contents of stack_section. Use
  102. // stack_section.start() as the region's starting address.
  103. void RegionFromSection() {
  104. string contents;
  105. ASSERT_TRUE(stack_section.GetContents(&contents));
  106. stack_region.Init(stack_section.start().Value(), contents);
  107. }
  108. // Fill RAW_CONTEXT with pseudo-random data, for round-trip checking.
  109. void BrandContext(MDRawContextX86 *raw_context) {
  110. u_int8_t x = 173;
  111. for (size_t i = 0; i < sizeof(*raw_context); i++)
  112. reinterpret_cast<u_int8_t *>(raw_context)[i] = (x += 17);
  113. }
  114. SystemInfo system_info;
  115. MDRawContextX86 raw_context;
  116. Section stack_section;
  117. MockMemoryRegion stack_region;
  118. MockCodeModule module1;
  119. MockCodeModule module2;
  120. MockCodeModule module3;
  121. MockCodeModule module4;
  122. MockCodeModule module5;
  123. MockCodeModule module6;
  124. MockCodeModules modules;
  125. MockSymbolSupplier supplier;
  126. BasicSourceLineResolver resolver;
  127. CallStack call_stack;
  128. const vector<StackFrame *> *frames;
  129. };
  130. class SanityCheck: public StackwalkerX86Fixture, public Test { };
  131. TEST_F(SanityCheck, NoResolver) {
  132. stack_section.start() = 0x80000000;
  133. stack_section.D32(0).D32(0); // end-of-stack marker
  134. RegionFromSection();
  135. raw_context.eip = 0x40000200;
  136. raw_context.ebp = 0x80000000;
  137. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  138. NULL, NULL);
  139. // This should succeed, even without a resolver or supplier.
  140. ASSERT_TRUE(walker.Walk(&call_stack));
  141. frames = call_stack.frames();
  142. StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
  143. // Check that the values from the original raw context made it
  144. // through to the context in the stack frame.
  145. EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
  146. }
  147. class GetContextFrame: public StackwalkerX86Fixture, public Test { };
  148. TEST_F(GetContextFrame, Simple) {
  149. stack_section.start() = 0x80000000;
  150. stack_section.D32(0).D32(0); // end-of-stack marker
  151. RegionFromSection();
  152. raw_context.eip = 0x40000200;
  153. raw_context.ebp = 0x80000000;
  154. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  155. &supplier, &resolver);
  156. ASSERT_TRUE(walker.Walk(&call_stack));
  157. frames = call_stack.frames();
  158. StackFrameX86 *frame = static_cast<StackFrameX86 *>(frames->at(0));
  159. // Check that the values from the original raw context made it
  160. // through to the context in the stack frame.
  161. EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
  162. }
  163. class GetCallerFrame: public StackwalkerX86Fixture, public Test { };
  164. // Walk a traditional frame. A traditional frame saves the caller's
  165. // %ebp just below the return address, and has its own %ebp pointing
  166. // at the saved %ebp.
  167. TEST_F(GetCallerFrame, Traditional) {
  168. stack_section.start() = 0x80000000;
  169. Label frame0_ebp, frame1_ebp;
  170. stack_section
  171. .Append(12, 0) // frame 0: space
  172. .Mark(&frame0_ebp) // frame 0 %ebp points here
  173. .D32(frame1_ebp) // frame 0: saved %ebp
  174. .D32(0x40008679) // frame 0: return address
  175. .Append(8, 0) // frame 1: space
  176. .Mark(&frame1_ebp) // frame 1 %ebp points here
  177. .D32(0) // frame 1: saved %ebp (stack end)
  178. .D32(0); // frame 1: return address (stack end)
  179. RegionFromSection();
  180. raw_context.eip = 0x4000c7a5;
  181. raw_context.esp = stack_section.start().Value();
  182. raw_context.ebp = frame0_ebp.Value();
  183. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  184. &supplier, &resolver);
  185. ASSERT_TRUE(walker.Walk(&call_stack));
  186. frames = call_stack.frames();
  187. ASSERT_EQ(2U, frames->size());
  188. { // To avoid reusing locals by mistake
  189. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  190. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  191. EXPECT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  192. EXPECT_EQ(0x4000c7a5U, frame0->instruction);
  193. EXPECT_EQ(0x4000c7a5U, frame0->context.eip);
  194. EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
  195. EXPECT_EQ(NULL, frame0->windows_frame_info);
  196. }
  197. { // To avoid reusing locals by mistake
  198. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  199. EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
  200. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  201. | StackFrameX86::CONTEXT_VALID_ESP
  202. | StackFrameX86::CONTEXT_VALID_EBP),
  203. frame1->context_validity);
  204. EXPECT_EQ(0x40008679U, frame1->instruction + 1);
  205. EXPECT_EQ(0x40008679U, frame1->context.eip);
  206. EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  207. EXPECT_EQ(NULL, frame1->windows_frame_info);
  208. }
  209. }
  210. // Walk a traditional frame, but use a bogus %ebp value, forcing a scan
  211. // of the stack for something that looks like a return address.
  212. TEST_F(GetCallerFrame, TraditionalScan) {
  213. stack_section.start() = 0x80000000;
  214. Label frame1_ebp;
  215. stack_section
  216. // frame 0
  217. .D32(0xf065dc76) // locals area:
  218. .D32(0x46ee2167) // garbage that doesn't look like
  219. .D32(0xbab023ec) // a return address
  220. .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan)
  221. .D32(0x4000129d) // return address
  222. // frame 1
  223. .Append(8, 0) // space
  224. .Mark(&frame1_ebp) // %ebp points here
  225. .D32(0) // saved %ebp (stack end)
  226. .D32(0); // return address (stack end)
  227. RegionFromSection();
  228. raw_context.eip = 0x4000f49d;
  229. raw_context.esp = stack_section.start().Value();
  230. // Make the frame pointer bogus, to make the stackwalker scan the stack
  231. // for something that looks like a return address.
  232. raw_context.ebp = 0xd43eed6e;
  233. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  234. &supplier, &resolver);
  235. ASSERT_TRUE(walker.Walk(&call_stack));
  236. frames = call_stack.frames();
  237. ASSERT_EQ(2U, frames->size());
  238. { // To avoid reusing locals by mistake
  239. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  240. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  241. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  242. EXPECT_EQ(0x4000f49dU, frame0->instruction);
  243. EXPECT_EQ(0x4000f49dU, frame0->context.eip);
  244. EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
  245. EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
  246. EXPECT_EQ(NULL, frame0->windows_frame_info);
  247. }
  248. { // To avoid reusing locals by mistake
  249. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  250. EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
  251. // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
  252. // walker does not actually fetch the EBP after a scan (forcing the
  253. // next frame to be scanned as well). But let's grandfather the existing
  254. // behavior in for now.
  255. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  256. | StackFrameX86::CONTEXT_VALID_ESP
  257. | StackFrameX86::CONTEXT_VALID_EBP),
  258. frame1->context_validity);
  259. EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
  260. EXPECT_EQ(0x4000129dU, frame1->context.eip);
  261. EXPECT_EQ(0x80000014U, frame1->context.esp);
  262. EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
  263. EXPECT_EQ(NULL, frame1->windows_frame_info);
  264. }
  265. }
  266. // Force scanning for a return address a long way down the stack
  267. TEST_F(GetCallerFrame, TraditionalScanLongWay) {
  268. stack_section.start() = 0x80000000;
  269. Label frame1_ebp;
  270. stack_section
  271. // frame 0
  272. .D32(0xf065dc76) // locals area:
  273. .D32(0x46ee2167) // garbage that doesn't look like
  274. .D32(0xbab023ec) // a return address
  275. .Append(20 * 4, 0) // a bunch of space
  276. .D32(frame1_ebp) // saved %ebp (%ebp fails to point here, forcing scan)
  277. .D32(0x4000129d) // return address
  278. // frame 1
  279. .Append(8, 0) // space
  280. .Mark(&frame1_ebp) // %ebp points here
  281. .D32(0) // saved %ebp (stack end)
  282. .D32(0); // return address (stack end)
  283. RegionFromSection();
  284. raw_context.eip = 0x4000f49d;
  285. raw_context.esp = stack_section.start().Value();
  286. // Make the frame pointer bogus, to make the stackwalker scan the stack
  287. // for something that looks like a return address.
  288. raw_context.ebp = 0xd43eed6e;
  289. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  290. &supplier, &resolver);
  291. ASSERT_TRUE(walker.Walk(&call_stack));
  292. frames = call_stack.frames();
  293. ASSERT_EQ(2U, frames->size());
  294. { // To avoid reusing locals by mistake
  295. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  296. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  297. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  298. EXPECT_EQ(0x4000f49dU, frame0->instruction);
  299. EXPECT_EQ(0x4000f49dU, frame0->context.eip);
  300. EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
  301. EXPECT_EQ(0xd43eed6eU, frame0->context.ebp);
  302. EXPECT_EQ(NULL, frame0->windows_frame_info);
  303. }
  304. { // To avoid reusing locals by mistake
  305. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  306. EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
  307. // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
  308. // walker does not actually fetch the EBP after a scan (forcing the
  309. // next frame to be scanned as well). But let's grandfather the existing
  310. // behavior in for now.
  311. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  312. | StackFrameX86::CONTEXT_VALID_ESP
  313. | StackFrameX86::CONTEXT_VALID_EBP),
  314. frame1->context_validity);
  315. EXPECT_EQ(0x4000129dU, frame1->instruction + 1);
  316. EXPECT_EQ(0x4000129dU, frame1->context.eip);
  317. EXPECT_EQ(0x80000064U, frame1->context.esp);
  318. EXPECT_EQ(0xd43eed6eU, frame1->context.ebp);
  319. EXPECT_EQ(NULL, frame1->windows_frame_info);
  320. }
  321. }
  322. // Use Windows frame data (a "STACK WIN 4" record, from a
  323. // FrameTypeFrameData DIA record) to walk a stack frame.
  324. TEST_F(GetCallerFrame, WindowsFrameData) {
  325. SetModuleSymbols(&module1,
  326. "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
  327. " $T2 $esp .cbSavedRegs + ="
  328. " $T0 .raSearchStart ="
  329. " $eip $T0 ^ ="
  330. " $esp $T0 4 + ="
  331. " $ebx $T2 4 - ^ ="
  332. " $edi $T2 8 - ^ ="
  333. " $esi $T2 12 - ^ ="
  334. " $ebp $T2 16 - ^ =\n");
  335. Label frame1_esp, frame1_ebp;
  336. stack_section.start() = 0x80000000;
  337. stack_section
  338. // frame 0
  339. .D32(frame1_ebp) // saved regs: %ebp
  340. .D32(0xa7120d1a) // %esi
  341. .D32(0x630891be) // %edi
  342. .D32(0x9068a878) // %ebx
  343. .D32(0xa08ea45f) // locals: unused
  344. .D32(0x40001350) // return address
  345. // frame 1
  346. .Mark(&frame1_esp)
  347. .Append(12, 0) // empty space
  348. .Mark(&frame1_ebp)
  349. .D32(0) // saved %ebp (stack end)
  350. .D32(0); // saved %eip (stack end)
  351. RegionFromSection();
  352. raw_context.eip = 0x4000aa85;
  353. raw_context.esp = stack_section.start().Value();
  354. raw_context.ebp = 0xf052c1de; // should not be needed to walk frame
  355. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  356. &supplier, &resolver);
  357. ASSERT_TRUE(walker.Walk(&call_stack));
  358. frames = call_stack.frames();
  359. ASSERT_EQ(2U, frames->size());
  360. { // To avoid reusing locals by mistake
  361. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  362. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  363. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  364. EXPECT_EQ(0x4000aa85U, frame0->instruction);
  365. EXPECT_EQ(0x4000aa85U, frame0->context.eip);
  366. EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
  367. EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
  368. EXPECT_TRUE(frame0->windows_frame_info != NULL);
  369. }
  370. { // To avoid reusing locals by mistake
  371. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  372. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  373. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  374. | StackFrameX86::CONTEXT_VALID_ESP
  375. | StackFrameX86::CONTEXT_VALID_EBP
  376. | StackFrameX86::CONTEXT_VALID_EBX
  377. | StackFrameX86::CONTEXT_VALID_ESI
  378. | StackFrameX86::CONTEXT_VALID_EDI),
  379. frame1->context_validity);
  380. EXPECT_EQ(0x40001350U, frame1->instruction + 1);
  381. EXPECT_EQ(0x40001350U, frame1->context.eip);
  382. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  383. EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  384. EXPECT_EQ(0x9068a878U, frame1->context.ebx);
  385. EXPECT_EQ(0xa7120d1aU, frame1->context.esi);
  386. EXPECT_EQ(0x630891beU, frame1->context.edi);
  387. EXPECT_EQ(NULL, frame1->windows_frame_info);
  388. }
  389. }
  390. // Use Windows frame data (a "STACK WIN 4" record, from a
  391. // FrameTypeFrameData DIA record) to walk a stack frame where the stack
  392. // is aligned and we must search
  393. TEST_F(GetCallerFrame, WindowsFrameDataAligned) {
  394. SetModuleSymbols(&module1,
  395. "STACK WIN 4 aa85 176 0 0 4 4 8 0 1"
  396. " $T1 .raSearch ="
  397. " $T0 $T1 4 - 8 @ ="
  398. " $ebp $T1 4 - ^ ="
  399. " $eip $T1 ^ ="
  400. " $esp $T1 4 + =");
  401. Label frame1_esp, frame1_ebp;
  402. stack_section.start() = 0x80000000;
  403. stack_section
  404. // frame 0
  405. .D32(0x0ffa0ffa) // unused saved register
  406. .D32(0xdeaddead) // locals
  407. .D32(0xbeefbeef)
  408. .D32(0) // 8-byte alignment
  409. .D32(frame1_ebp)
  410. .D32(0x5000129d) // return address
  411. // frame 1
  412. .Mark(&frame1_esp)
  413. .D32(0x1) // parameter
  414. .Mark(&frame1_ebp)
  415. .D32(0) // saved %ebp (stack end)
  416. .D32(0); // saved %eip (stack end)
  417. RegionFromSection();
  418. raw_context.eip = 0x4000aa85;
  419. raw_context.esp = stack_section.start().Value();
  420. raw_context.ebp = 0xf052c1de; // should not be needed to walk frame
  421. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  422. &supplier, &resolver);
  423. ASSERT_TRUE(walker.Walk(&call_stack));
  424. frames = call_stack.frames();
  425. ASSERT_EQ(2U, frames->size());
  426. { // To avoid reusing locals by mistake
  427. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  428. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  429. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  430. EXPECT_EQ(0x4000aa85U, frame0->instruction);
  431. EXPECT_EQ(0x4000aa85U, frame0->context.eip);
  432. EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
  433. EXPECT_EQ(0xf052c1deU, frame0->context.ebp);
  434. EXPECT_TRUE(frame0->windows_frame_info != NULL);
  435. }
  436. { // To avoid reusing locals by mistake
  437. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  438. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  439. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  440. | StackFrameX86::CONTEXT_VALID_ESP
  441. | StackFrameX86::CONTEXT_VALID_EBP),
  442. frame1->context_validity);
  443. EXPECT_EQ(0x5000129dU, frame1->instruction + 1);
  444. EXPECT_EQ(0x5000129dU, frame1->context.eip);
  445. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  446. EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  447. EXPECT_EQ(NULL, frame1->windows_frame_info);
  448. }
  449. }
  450. // Use Windows frame data (a "STACK WIN 4" record, from a
  451. // FrameTypeFrameData DIA record) to walk a frame, and depend on the
  452. // parameter size from the callee as well.
  453. TEST_F(GetCallerFrame, WindowsFrameDataParameterSize) {
  454. SetModuleSymbols(&module1, "FUNC 1000 100 c module1::wheedle\n");
  455. SetModuleSymbols(&module2,
  456. // Note bogus parameter size in FUNC record; the stack walker
  457. // should prefer the STACK WIN record, and see '4' below.
  458. "FUNC aa85 176 beef module2::whine\n"
  459. "STACK WIN 4 aa85 176 0 0 4 10 4 0 1"
  460. " $T2 $esp .cbLocals + .cbSavedRegs + ="
  461. " $T0 .raSearchStart ="
  462. " $eip $T0 ^ ="
  463. " $esp $T0 4 + ="
  464. " $ebp $T0 20 - ^ ="
  465. " $ebx $T0 8 - ^ =\n");
  466. Label frame0_esp, frame0_ebp;
  467. Label frame1_esp;
  468. Label frame2_esp, frame2_ebp;
  469. stack_section.start() = 0x80000000;
  470. stack_section
  471. // frame 0, in module1::wheedle. Traditional frame.
  472. .Mark(&frame0_esp)
  473. .Append(16, 0) // frame space
  474. .Mark(&frame0_ebp)
  475. .D32(0x6fa902e0) // saved %ebp. Not a frame pointer.
  476. .D32(0x5000aa95) // return address, in module2::whine
  477. // frame 1, in module2::whine. FrameData frame.
  478. .Mark(&frame1_esp)
  479. .D32(0xbaa0cb7a) // argument 3 passed to module1::wheedle
  480. .D32(0xbdc92f9f) // argument 2
  481. .D32(0x0b1d8442) // argument 1
  482. .D32(frame2_ebp) // saved %ebp
  483. .D32(0xb1b90a15) // unused
  484. .D32(0xf18e072d) // unused
  485. .D32(0x2558c7f3) // saved %ebx
  486. .D32(0x0365e25e) // unused
  487. .D32(0x2a179e38) // return address; $T0 points here
  488. // frame 2, in no module
  489. .Mark(&frame2_esp)
  490. .Append(12, 0) // empty space
  491. .Mark(&frame2_ebp)
  492. .D32(0) // saved %ebp (stack end)
  493. .D32(0); // saved %eip (stack end)
  494. RegionFromSection();
  495. raw_context.eip = 0x40001004; // in module1::wheedle
  496. raw_context.esp = stack_section.start().Value();
  497. raw_context.ebp = frame0_ebp.Value();
  498. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  499. &supplier, &resolver);
  500. ASSERT_TRUE(walker.Walk(&call_stack));
  501. frames = call_stack.frames();
  502. ASSERT_EQ(3U, frames->size());
  503. { // To avoid reusing locals by mistake
  504. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  505. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  506. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  507. EXPECT_EQ(0x40001004U, frame0->instruction);
  508. EXPECT_EQ(0x40001004U, frame0->context.eip);
  509. EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
  510. EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
  511. EXPECT_EQ(&module1, frame0->module);
  512. EXPECT_EQ("module1::wheedle", frame0->function_name);
  513. EXPECT_EQ(0x40001000U, frame0->function_base);
  514. // The FUNC record for module1::wheedle should have produced a
  515. // WindowsFrameInfo structure with only the parameter size valid.
  516. ASSERT_TRUE(frame0->windows_frame_info != NULL);
  517. EXPECT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
  518. frame0->windows_frame_info->valid);
  519. EXPECT_EQ(WindowsFrameInfo::STACK_INFO_UNKNOWN,
  520. frame0->windows_frame_info->type_);
  521. EXPECT_EQ(12U, frame0->windows_frame_info->parameter_size);
  522. }
  523. { // To avoid reusing locals by mistake
  524. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  525. EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
  526. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  527. | StackFrameX86::CONTEXT_VALID_ESP
  528. | StackFrameX86::CONTEXT_VALID_EBP),
  529. frame1->context_validity);
  530. EXPECT_EQ(0x5000aa95U, frame1->instruction + 1);
  531. EXPECT_EQ(0x5000aa95U, frame1->context.eip);
  532. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  533. EXPECT_EQ(0x6fa902e0U, frame1->context.ebp);
  534. EXPECT_EQ(&module2, frame1->module);
  535. EXPECT_EQ("module2::whine", frame1->function_name);
  536. EXPECT_EQ(0x5000aa85U, frame1->function_base);
  537. ASSERT_TRUE(frame1->windows_frame_info != NULL);
  538. EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
  539. EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
  540. frame1->windows_frame_info->type_);
  541. // This should not see the 0xbeef parameter size from the FUNC
  542. // record, but should instead see the STACK WIN record.
  543. EXPECT_EQ(4U, frame1->windows_frame_info->parameter_size);
  544. }
  545. { // To avoid reusing locals by mistake
  546. StackFrameX86 *frame2 = static_cast<StackFrameX86 *>(frames->at(2));
  547. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame2->trust);
  548. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  549. | StackFrameX86::CONTEXT_VALID_ESP
  550. | StackFrameX86::CONTEXT_VALID_EBP
  551. | StackFrameX86::CONTEXT_VALID_EBX),
  552. frame2->context_validity);
  553. EXPECT_EQ(0x2a179e38U, frame2->instruction + 1);
  554. EXPECT_EQ(0x2a179e38U, frame2->context.eip);
  555. EXPECT_EQ(frame2_esp.Value(), frame2->context.esp);
  556. EXPECT_EQ(frame2_ebp.Value(), frame2->context.ebp);
  557. EXPECT_EQ(0x2558c7f3U, frame2->context.ebx);
  558. EXPECT_EQ(NULL, frame2->module);
  559. EXPECT_EQ(NULL, frame2->windows_frame_info);
  560. }
  561. }
  562. // Use Windows frame data (a "STACK WIN 4" record, from a
  563. // FrameTypeFrameData DIA record) to walk a stack frame, where the
  564. // expression fails to yield both an $eip and an $ebp value, and the stack
  565. // walker must scan.
  566. TEST_F(GetCallerFrame, WindowsFrameDataScan) {
  567. SetModuleSymbols(&module1,
  568. "STACK WIN 4 c8c 111 0 0 4 10 4 0 1 bad program string\n");
  569. // Mark frame 1's PC as the end of the stack.
  570. SetModuleSymbols(&module2,
  571. "FUNC 7c38 accf 0 module2::function\n"
  572. "STACK WIN 4 7c38 accf 0 0 4 10 4 0 1 $eip 0 = $ebp 0 =\n");
  573. Label frame1_esp;
  574. stack_section.start() = 0x80000000;
  575. stack_section
  576. // frame 0
  577. .Append(16, 0x2a) // unused, garbage
  578. .D32(0x50007ce9) // return address
  579. // frame 1
  580. .Mark(&frame1_esp)
  581. .Append(8, 0); // empty space
  582. RegionFromSection();
  583. raw_context.eip = 0x40000c9c;
  584. raw_context.esp = stack_section.start().Value();
  585. raw_context.ebp = 0x2ae314cd; // should not be needed to walk frame
  586. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  587. &supplier, &resolver);
  588. ASSERT_TRUE(walker.Walk(&call_stack));
  589. frames = call_stack.frames();
  590. ASSERT_EQ(2U, frames->size());
  591. { // To avoid reusing locals by mistake
  592. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  593. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  594. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  595. EXPECT_EQ(0x40000c9cU, frame0->instruction);
  596. EXPECT_EQ(0x40000c9cU, frame0->context.eip);
  597. EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
  598. EXPECT_EQ(0x2ae314cdU, frame0->context.ebp);
  599. EXPECT_TRUE(frame0->windows_frame_info != NULL);
  600. }
  601. { // To avoid reusing locals by mistake
  602. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  603. EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
  604. // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the walker
  605. // does not actually fetch the EBP after a scan (forcing the next frame
  606. // to be scanned as well). But let's grandfather the existing behavior in
  607. // for now.
  608. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  609. | StackFrameX86::CONTEXT_VALID_ESP
  610. | StackFrameX86::CONTEXT_VALID_EBP),
  611. frame1->context_validity);
  612. EXPECT_EQ(0x50007ce9U, frame1->instruction + 1);
  613. EXPECT_EQ(0x50007ce9U, frame1->context.eip);
  614. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  615. EXPECT_TRUE(frame1->windows_frame_info != NULL);
  616. }
  617. }
  618. // Use Windows frame data (a "STACK WIN 4" record, from a
  619. // FrameTypeFrameData DIA record) to walk a stack frame, where the
  620. // expression yields an $eip that falls outside of any module, and the
  621. // stack walker must scan.
  622. TEST_F(GetCallerFrame, WindowsFrameDataBadEIPScan) {
  623. SetModuleSymbols(&module1,
  624. "STACK WIN 4 6e6 e7 0 0 0 8 4 0 1"
  625. // A traditional frame, actually.
  626. " $eip $ebp 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =\n");
  627. // Mark frame 1's PC as the end of the stack.
  628. SetModuleSymbols(&module2,
  629. "FUNC cfdb 8406 0 module2::function\n"
  630. "STACK WIN 4 cfdb 8406 0 0 0 0 0 0 1 $eip 0 = $ebp 0 =\n");
  631. stack_section.start() = 0x80000000;
  632. // In this stack, the context's %ebp is pointing at the wrong place, so
  633. // the stack walker needs to scan to find the return address, and then
  634. // scan again to find the caller's saved %ebp.
  635. Label frame0_ebp, frame1_ebp, frame1_esp;
  636. stack_section
  637. // frame 0
  638. .Append(8, 0x2a) // garbage
  639. .Mark(&frame0_ebp) // frame 0 %ebp points here, but should point
  640. // at *** below
  641. // The STACK WIN record says that the following two values are
  642. // frame 1's saved %ebp and return address, but the %ebp is wrong;
  643. // they're garbage. The stack walker will scan for the right values.
  644. .D32(0x3d937b2b) // alleged to be frame 1's saved %ebp
  645. .D32(0x17847f5b) // alleged to be frame 1's return address
  646. .D32(frame1_ebp) // frame 1's real saved %ebp; scan will find
  647. .D32(0x2b2b2b2b) // first word of realigned register save area
  648. // *** frame 0 %ebp ought to be pointing here
  649. .D32(0x2c2c2c2c) // realigned locals area
  650. .D32(0x5000d000) // frame 1's real saved %eip; scan will find
  651. // Frame 1, in module2::function. The STACK WIN record describes
  652. // this as the oldest frame, without referring to its contents, so
  653. // we needn't to provide any actual data here.
  654. .Mark(&frame1_esp)
  655. .Mark(&frame1_ebp) // frame 1 %ebp points here
  656. // A dummy value for frame 1's %ebp to point at. The scan recognizes the
  657. // saved %ebp because it points to a valid word in the stack memory region.
  658. .D32(0x2d2d2d2d);
  659. RegionFromSection();
  660. raw_context.eip = 0x40000700;
  661. raw_context.esp = stack_section.start().Value();
  662. raw_context.ebp = frame0_ebp.Value();
  663. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  664. &supplier, &resolver);
  665. ASSERT_TRUE(walker.Walk(&call_stack));
  666. frames = call_stack.frames();
  667. ASSERT_EQ(2U, frames->size());
  668. { // To avoid reusing locals by mistake
  669. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  670. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  671. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  672. EXPECT_EQ(0x40000700U, frame0->instruction);
  673. EXPECT_EQ(0x40000700U, frame0->context.eip);
  674. EXPECT_EQ(stack_section.start().Value(), frame0->context.esp);
  675. EXPECT_EQ(frame0_ebp.Value(), frame0->context.ebp);
  676. EXPECT_TRUE(frame0->windows_frame_info != NULL);
  677. }
  678. { // To avoid reusing locals by mistake
  679. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  680. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI_SCAN, frame1->trust);
  681. // I'd argue that CONTEXT_VALID_EBP shouldn't be here, since the
  682. // walker does not actually fetch the EBP after a scan (forcing the
  683. // next frame to be scanned as well). But let's grandfather the existing
  684. // behavior in for now.
  685. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  686. | StackFrameX86::CONTEXT_VALID_ESP
  687. | StackFrameX86::CONTEXT_VALID_EBP),
  688. frame1->context_validity);
  689. EXPECT_EQ(0x5000d000U, frame1->instruction + 1);
  690. EXPECT_EQ(0x5000d000U, frame1->context.eip);
  691. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  692. EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  693. EXPECT_TRUE(frame1->windows_frame_info != NULL);
  694. }
  695. }
  696. // Use Windows FrameTypeFPO data to walk a stack frame for a function that
  697. // does not modify %ebp from the value it had in the caller.
  698. TEST_F(GetCallerFrame, WindowsFPOUnchangedEBP) {
  699. SetModuleSymbols(&module1,
  700. // Note bogus parameter size in FUNC record; the walker
  701. // should prefer the STACK WIN record, and see the '8' below.
  702. "FUNC e8a8 100 feeb module1::discombobulated\n"
  703. "STACK WIN 0 e8a8 100 0 0 8 4 10 0 0 0\n");
  704. Label frame0_esp;
  705. Label frame1_esp, frame1_ebp;
  706. stack_section.start() = 0x80000000;
  707. stack_section
  708. // frame 0, in module1::wheedle. FrameTypeFPO (STACK WIN 0) frame.
  709. .Mark(&frame0_esp)
  710. // no outgoing parameters; this is the youngest frame.
  711. .D32(0x7c521352) // four bytes of saved registers
  712. .Append(0x10, 0x42) // local area
  713. .D32(0x40009b5b) // return address, in module1, no function
  714. // frame 1, in module1, no function.
  715. .Mark(&frame1_esp)
  716. .D32(0xf60ea7fc) // junk
  717. .Mark(&frame1_ebp)
  718. .D32(0) // saved %ebp (stack end)
  719. .D32(0); // saved %eip (stack end)
  720. RegionFromSection();
  721. raw_context.eip = 0x4000e8b8; // in module1::whine
  722. raw_context.esp = stack_section.start().Value();
  723. // Frame pointer unchanged from caller.
  724. raw_context.ebp = frame1_ebp.Value();
  725. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  726. &supplier, &resolver);
  727. ASSERT_TRUE(walker.Walk(&call_stack));
  728. frames = call_stack.frames();
  729. ASSERT_EQ(2U, frames->size());
  730. { // To avoid reusing locals by mistake
  731. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  732. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  733. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  734. EXPECT_EQ(0x4000e8b8U, frame0->instruction);
  735. EXPECT_EQ(0x4000e8b8U, frame0->context.eip);
  736. EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
  737. EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp); // unchanged from caller
  738. EXPECT_EQ(&module1, frame0->module);
  739. EXPECT_EQ("module1::discombobulated", frame0->function_name);
  740. EXPECT_EQ(0x4000e8a8U, frame0->function_base);
  741. // The STACK WIN record for module1::discombobulated should have
  742. // produced a fully populated WindowsFrameInfo structure.
  743. ASSERT_TRUE(frame0->windows_frame_info != NULL);
  744. EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
  745. EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
  746. frame0->windows_frame_info->type_);
  747. EXPECT_EQ(0x10U, frame0->windows_frame_info->local_size);
  748. }
  749. { // To avoid reusing locals by mistake
  750. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  751. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  752. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  753. | StackFrameX86::CONTEXT_VALID_ESP
  754. | StackFrameX86::CONTEXT_VALID_EBP),
  755. frame1->context_validity);
  756. EXPECT_EQ(0x40009b5bU, frame1->instruction + 1);
  757. EXPECT_EQ(0x40009b5bU, frame1->context.eip);
  758. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  759. EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  760. EXPECT_EQ(&module1, frame1->module);
  761. EXPECT_EQ("", frame1->function_name);
  762. EXPECT_EQ(NULL, frame1->windows_frame_info);
  763. }
  764. }
  765. // Use Windows FrameTypeFPO data to walk a stack frame for a function
  766. // that uses %ebp for its own purposes, saving the value it had in the
  767. // caller in the standard place in the saved register area.
  768. TEST_F(GetCallerFrame, WindowsFPOUsedEBP) {
  769. SetModuleSymbols(&module1,
  770. // Note bogus parameter size in FUNC record; the walker
  771. // should prefer the STACK WIN record, and see the '8' below.
  772. "FUNC 9aa8 e6 abbe module1::RaisedByTheAliens\n"
  773. "STACK WIN 0 9aa8 e6 a 0 10 8 4 0 0 1\n");
  774. Label frame0_esp;
  775. Label frame1_esp, frame1_ebp;
  776. stack_section.start() = 0x80000000;
  777. stack_section
  778. // frame 0, in module1::wheedle. FrameTypeFPO (STACK WIN 0) frame.
  779. .Mark(&frame0_esp)
  780. // no outgoing parameters; this is the youngest frame.
  781. .D32(frame1_ebp) // saved register area: saved %ebp
  782. .D32(0xb68bd5f9) // saved register area: something else
  783. .D32(0xd25d05fc) // local area
  784. .D32(0x4000debe) // return address, in module1, no function
  785. // frame 1, in module1, no function.
  786. .Mark(&frame1_esp)
  787. .D32(0xf0c9a974) // junk
  788. .Mark(&frame1_ebp)
  789. .D32(0) // saved %ebp (stack end)
  790. .D32(0); // saved %eip (stack end)
  791. RegionFromSection();
  792. raw_context.eip = 0x40009ab8; // in module1::RaisedByTheAliens
  793. raw_context.esp = stack_section.start().Value();
  794. // RaisedByTheAliens uses %ebp for its own mysterious purposes.
  795. raw_context.ebp = 0xecbdd1a5;
  796. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  797. &supplier, &resolver);
  798. ASSERT_TRUE(walker.Walk(&call_stack));
  799. frames = call_stack.frames();
  800. ASSERT_EQ(2U, frames->size());
  801. { // To avoid reusing locals by mistake
  802. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  803. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  804. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  805. EXPECT_EQ(0x40009ab8U, frame0->instruction);
  806. EXPECT_EQ(0x40009ab8U, frame0->context.eip);
  807. EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
  808. EXPECT_EQ(0xecbdd1a5, frame0->context.ebp);
  809. EXPECT_EQ(&module1, frame0->module);
  810. EXPECT_EQ("module1::RaisedByTheAliens", frame0->function_name);
  811. EXPECT_EQ(0x40009aa8U, frame0->function_base);
  812. // The STACK WIN record for module1::RaisedByTheAliens should have
  813. // produced a fully populated WindowsFrameInfo structure.
  814. ASSERT_TRUE(frame0->windows_frame_info != NULL);
  815. EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
  816. EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
  817. frame0->windows_frame_info->type_);
  818. EXPECT_EQ("", frame0->windows_frame_info->program_string);
  819. EXPECT_TRUE(frame0->windows_frame_info->allocates_base_pointer);
  820. }
  821. { // To avoid reusing locals by mistake
  822. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  823. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  824. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  825. | StackFrameX86::CONTEXT_VALID_ESP
  826. | StackFrameX86::CONTEXT_VALID_EBP),
  827. frame1->context_validity);
  828. EXPECT_EQ(0x4000debeU, frame1->instruction + 1);
  829. EXPECT_EQ(0x4000debeU, frame1->context.eip);
  830. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  831. EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  832. EXPECT_EQ(&module1, frame1->module);
  833. EXPECT_EQ("", frame1->function_name);
  834. EXPECT_EQ(NULL, frame1->windows_frame_info);
  835. }
  836. }
  837. // This is a regression unit test which covers a bug which has to do with
  838. // FPO-optimized Windows system call stubs in the context frame. There is
  839. // a more recent Windows system call dispatch mechanism which differs from
  840. // the one which is being tested here. The newer system call dispatch
  841. // mechanism creates an extra context frame (KiFastSystemCallRet).
  842. TEST_F(GetCallerFrame, WindowsFPOSystemCall) {
  843. SetModuleSymbols(&module3, // ntdll.dll
  844. "PUBLIC 1f8ac c ZwWaitForSingleObject\n"
  845. "STACK WIN 0 1f8ac 1b 0 0 c 0 0 0 0 0\n");
  846. SetModuleSymbols(&module4, // kernelbase.dll
  847. "PUBLIC 109f9 c WaitForSingleObjectEx\n"
  848. "PUBLIC 36590 0 _except_handler4\n"
  849. "STACK WIN 4 109f9 df c 0 c c 48 0 1 $T0 $ebp = $eip "
  850. "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
  851. "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
  852. "STACK WIN 4 36590 154 17 0 10 0 14 0 1 $T0 $ebp = $eip "
  853. "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L $T0 "
  854. ".cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
  855. SetModuleSymbols(&module5, // kernel32.dll
  856. "PUBLIC 11136 8 WaitForSingleObject\n"
  857. "PUBLIC 11151 c WaitForSingleObjectExImplementation\n"
  858. "STACK WIN 4 11136 16 5 0 8 0 0 0 1 $T0 $ebp = $eip "
  859. "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
  860. "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n"
  861. "STACK WIN 4 11151 7a 5 0 c 0 0 0 1 $T0 $ebp = $eip "
  862. "$T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
  863. "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =\n");
  864. SetModuleSymbols(&module6, // chrome.dll
  865. "FILE 7038 some_file_name.h\n"
  866. "FILE 839776 some_file_name.cc\n"
  867. "FUNC 217fda 17 4 function_217fda\n"
  868. "217fda 4 102 839776\n"
  869. "FUNC 217ff1 a 4 function_217ff1\n"
  870. "217ff1 0 594 7038\n"
  871. "217ff1 a 596 7038\n"
  872. "STACK WIN 0 217ff1 a 0 0 4 0 0 0 0 0\n");
  873. Label frame0_esp, frame1_esp;
  874. Label frame1_ebp, frame2_ebp, frame3_ebp;
  875. stack_section.start() = 0x002ff290;
  876. stack_section
  877. .Mark(&frame0_esp)
  878. .D32(0x771ef8c1) // EIP in frame 0 (system call)
  879. .D32(0x75fa0a91) // return address of frame 0
  880. .Mark(&frame1_esp)
  881. .D32(0x000017b0) // args to child
  882. .D32(0x00000000)
  883. .D32(0x002ff2d8)
  884. .D32(0x88014a2e)
  885. .D32(0x002ff364)
  886. .D32(0x000017b0)
  887. .D32(0x00000000)
  888. .D32(0x00000024)
  889. .D32(0x00000001)
  890. .D32(0x00000000)
  891. .D32(0x00000000)
  892. .D32(0x00000000)
  893. .D32(0x00000000)
  894. .D32(0x00000000)
  895. .D32(0x00000000)
  896. .D32(0x00000000)
  897. .D32(0x9e3b9800)
  898. .D32(0xfffffff7)
  899. .D32(0x00000000)
  900. .D32(0x002ff2a4)
  901. .D32(0x64a07ff1) // random value to be confused with a return address
  902. .D32(0x002ff8dc)
  903. .D32(0x75fc6590) // random value to be confused with a return address
  904. .D32(0xfdd2c6ea)
  905. .D32(0x00000000)
  906. .Mark(&frame1_ebp)
  907. .D32(frame2_ebp) // Child EBP
  908. .D32(0x75741194) // return address of frame 1
  909. .D32(0x000017b0) // args to child
  910. .D32(0x0036ee80)
  911. .D32(0x00000000)
  912. .D32(0x65bc7d14)
  913. .Mark(&frame2_ebp)
  914. .D32(frame3_ebp) // Child EBP
  915. .D32(0x75741148) // return address of frame 2
  916. .D32(0x000017b0) // args to child
  917. .D32(0x0036ee80)
  918. .D32(0x00000000)
  919. .Mark(&frame3_ebp)
  920. .D32(0) // saved %ebp (stack end)
  921. .D32(0); // saved %eip (stack end)
  922. RegionFromSection();
  923. raw_context.eip = 0x771ef8c1; // in ntdll::ZwWaitForSingleObject
  924. raw_context.esp = stack_section.start().Value();
  925. ASSERT_TRUE(raw_context.esp == frame0_esp.Value());
  926. raw_context.ebp = frame1_ebp.Value();
  927. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  928. &supplier, &resolver);
  929. ASSERT_TRUE(walker.Walk(&call_stack));
  930. frames = call_stack.frames();
  931. ASSERT_EQ(4U, frames->size());
  932. { // To avoid reusing locals by mistake
  933. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  934. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  935. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  936. EXPECT_EQ(0x771ef8c1U, frame0->instruction);
  937. EXPECT_EQ(0x771ef8c1U, frame0->context.eip);
  938. EXPECT_EQ(frame0_esp.Value(), frame0->context.esp);
  939. EXPECT_EQ(frame1_ebp.Value(), frame0->context.ebp);
  940. EXPECT_EQ(&module3, frame0->module);
  941. EXPECT_EQ("ZwWaitForSingleObject", frame0->function_name);
  942. // The STACK WIN record for module3!ZwWaitForSingleObject should have
  943. // produced a fully populated WindowsFrameInfo structure.
  944. ASSERT_TRUE(frame0->windows_frame_info != NULL);
  945. EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame0->windows_frame_info->valid);
  946. EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FPO,
  947. frame0->windows_frame_info->type_);
  948. EXPECT_EQ("", frame0->windows_frame_info->program_string);
  949. EXPECT_FALSE(frame0->windows_frame_info->allocates_base_pointer);
  950. }
  951. { // To avoid reusing locals by mistake
  952. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  953. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  954. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP
  955. | StackFrameX86::CONTEXT_VALID_ESP
  956. | StackFrameX86::CONTEXT_VALID_EBP),
  957. frame1->context_validity);
  958. EXPECT_EQ(0x75fa0a91U, frame1->instruction + 1);
  959. EXPECT_EQ(0x75fa0a91U, frame1->context.eip);
  960. EXPECT_EQ(frame1_esp.Value(), frame1->context.esp);
  961. EXPECT_EQ(frame1_ebp.Value(), frame1->context.ebp);
  962. EXPECT_EQ(&module4, frame1->module);
  963. EXPECT_EQ("WaitForSingleObjectEx", frame1->function_name);
  964. // The STACK WIN record for module4!WaitForSingleObjectEx should have
  965. // produced a fully populated WindowsFrameInfo structure.
  966. ASSERT_TRUE(frame1->windows_frame_info != NULL);
  967. EXPECT_EQ(WindowsFrameInfo::VALID_ALL, frame1->windows_frame_info->valid);
  968. EXPECT_EQ(WindowsFrameInfo::STACK_INFO_FRAME_DATA,
  969. frame1->windows_frame_info->type_);
  970. EXPECT_EQ("$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $L "
  971. "$T0 .cbSavedRegs - = $P $T0 8 + .cbParams + =",
  972. frame1->windows_frame_info->program_string);
  973. EXPECT_FALSE(frame1->windows_frame_info->allocates_base_pointer);
  974. }
  975. }
  976. struct CFIFixture: public StackwalkerX86Fixture {
  977. CFIFixture() {
  978. // Provide a bunch of STACK CFI records; individual tests walk to the
  979. // caller from every point in this series, expecting to find the same
  980. // set of register values.
  981. SetModuleSymbols(&module1,
  982. // The youngest frame's function.
  983. "FUNC 4000 1000 10 enchiridion\n"
  984. // Initially, just a return address.
  985. "STACK CFI INIT 4000 100 .cfa: $esp 4 + .ra: .cfa 4 - ^\n"
  986. // Push %ebx.
  987. "STACK CFI 4001 .cfa: $esp 8 + $ebx: .cfa 8 - ^\n"
  988. // Move %esi into %ebx. Weird, but permitted.
  989. "STACK CFI 4002 $esi: $ebx\n"
  990. // Allocate frame space, and save %edi.
  991. "STACK CFI 4003 .cfa: $esp 20 + $edi: .cfa 16 - ^\n"
  992. // Put the return address in %edi.
  993. "STACK CFI 4005 .ra: $edi\n"
  994. // Save %ebp, and use it as a frame pointer.
  995. "STACK CFI 4006 .cfa: $ebp 8 + $ebp: .cfa 12 - ^\n"
  996. // The calling function.
  997. "FUNC 5000 1000 10 epictetus\n"
  998. // Mark it as end of stack.
  999. "STACK CFI INIT 5000 1000 .cfa: $esp .ra 0\n");
  1000. // Provide some distinctive values for the caller's registers.
  1001. expected.esp = 0x80000000;
  1002. expected.eip = 0x40005510;
  1003. expected.ebp = 0xc0d4aab9;
  1004. expected.ebx = 0x60f20ce6;
  1005. expected.esi = 0x53d1379d;
  1006. expected.edi = 0xafbae234;
  1007. // By default, registers are unchanged.
  1008. raw_context = expected;
  1009. }
  1010. // Walk the stack, using stack_section as the contents of the stack
  1011. // and raw_context as the current register values. (Set
  1012. // raw_context.esp to the stack's starting address.) Expect two
  1013. // stack frames; in the older frame, expect the callee-saves
  1014. // registers to have values matching those in 'expected'.
  1015. void CheckWalk() {
  1016. RegionFromSection();
  1017. raw_context.esp = stack_section.start().Value();
  1018. StackwalkerX86 walker(&system_info, &raw_context, &stack_region, &modules,
  1019. &supplier, &resolver);
  1020. ASSERT_TRUE(walker.Walk(&call_stack));
  1021. frames = call_stack.frames();
  1022. ASSERT_EQ(2U, frames->size());
  1023. { // To avoid reusing locals by mistake
  1024. StackFrameX86 *frame0 = static_cast<StackFrameX86 *>(frames->at(0));
  1025. EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
  1026. ASSERT_EQ(StackFrameX86::CONTEXT_VALID_ALL, frame0->context_validity);
  1027. EXPECT_EQ("enchiridion", frame0->function_name);
  1028. EXPECT_EQ(0x40004000U, frame0->function_base);
  1029. ASSERT_TRUE(frame0->windows_frame_info != NULL);
  1030. ASSERT_EQ(WindowsFrameInfo::VALID_PARAMETER_SIZE,
  1031. frame0->windows_frame_info->valid);
  1032. ASSERT_TRUE(frame0->cfi_frame_info != NULL);
  1033. }
  1034. { // To avoid reusing locals by mistake
  1035. StackFrameX86 *frame1 = static_cast<StackFrameX86 *>(frames->at(1));
  1036. EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
  1037. ASSERT_EQ((StackFrameX86::CONTEXT_VALID_EIP |
  1038. StackFrameX86::CONTEXT_VALID_ESP |
  1039. StackFrameX86::CONTEXT_VALID_EBP |
  1040. StackFrameX86::CONTEXT_VALID_EBX |
  1041. StackFrameX86::CONTEXT_VALID_ESI |
  1042. StackFrameX86::CONTEXT_VALID_EDI),
  1043. frame1->context_validity);
  1044. EXPECT_EQ(expected.eip, frame1->context.eip);
  1045. EXPECT_EQ(expected.esp, frame1->context.esp);
  1046. EXPECT_EQ(expected.ebp, frame1->context.ebp);
  1047. EXPECT_EQ(expected.ebx, frame1->context.ebx);
  1048. EXPECT_EQ(expected.esi, frame1->context.esi);
  1049. EXPECT_EQ(expected.edi, frame1->context.edi);
  1050. EXPECT_EQ("epictetus", frame1->function_name);
  1051. }
  1052. }
  1053. // The values the stack walker should find for the caller's registers.
  1054. MDRawContextX86 expected;
  1055. };
  1056. class CFI: public CFIFixture, public Test { };
  1057. TEST_F(CFI, At4000) {
  1058. Label frame1_esp = expected.esp;
  1059. stack_section
  1060. .D32(0x40005510) // return address
  1061. .Mark(&frame1_esp); // This effectively sets stack_section.start().
  1062. raw_context.eip = 0x40004000;
  1063. CheckWalk();
  1064. }
  1065. TEST_F(CFI, At4001) {
  1066. Label frame1_esp = expected.esp;
  1067. stack_section
  1068. .D32(0x60f20ce6) // saved %ebx
  1069. .D32(0x40005510) // return address
  1070. .Mark(&frame1_esp); // This effectively sets stack_section.start().
  1071. raw_context.eip = 0x40004001;
  1072. raw_context.ebx = 0x91aa9a8b; // callee's %ebx value
  1073. CheckWalk();
  1074. }
  1075. TEST_F(CFI, At4002) {
  1076. Label frame1_esp = expected.esp;
  1077. stack_section
  1078. .D32(0x60f20ce6) // saved %ebx
  1079. .D32(0x40005510) // return address
  1080. .Mark(&frame1_esp); // This effectively sets stack_section.start().
  1081. raw_context.eip = 0x40004002;
  1082. raw_context.ebx = 0x53d1379d; // saved %esi
  1083. raw_context.esi = 0xa5c790ed; // callee's %esi value
  1084. CheckWalk();
  1085. }
  1086. TEST_F(CFI, At4003) {
  1087. Label frame1_esp = expected.esp;
  1088. stack_section
  1089. .D32(0x56ec3db7) // garbage
  1090. .D32(0xafbae234) // saved %edi
  1091. .D32(0x53d67131) // garbage
  1092. .D32(0x60f20ce6) // saved %ebx
  1093. .D32(0x40005510) // return address
  1094. .Mark(&frame1_esp); // This effectively sets stack_section.start().
  1095. raw_context.eip = 0x40004003;
  1096. raw_context.ebx = 0x53d1379d; // saved %esi
  1097. raw_context.esi = 0xa97f229d; // callee's %esi
  1098. raw_context.edi = 0xb05cc997; // callee's %edi
  1099. CheckWalk();
  1100. }
  1101. // The results here should be the same as those at module offset
  1102. // 0x4003.
  1103. TEST_F(CFI, At4004) {
  1104. Label frame1_esp = expected.esp;
  1105. stack_section
  1106. .D32(0xe29782c2) // garbage
  1107. .D32(0xafbae234) // saved %edi
  1108. .D32(0x5ba29ce9) // garbage
  1109. .D32(0x60f20ce6) // saved %ebx
  1110. .D32(0x40005510) // return address
  1111. .Mark(&frame1_esp); // This effectively sets stack_section.start().
  1112. raw_context.eip = 0x40004004;
  1113. raw_context.ebx = 0x53d1379d; // saved %esi
  1114. raw_context.esi = 0x0fb7dc4e; // callee's %esi
  1115. raw_context.edi = 0x993b4280; // callee's %edi
  1116. CheckWalk();
  1117. }
  1118. TEST_F(CFI, At4005) {
  1119. Label frame1_esp = expected.esp;
  1120. stack_section
  1121. .D32(0xe29782c2) // garbage
  1122. .D32(0xafbae234) // saved %edi
  1123. .D32(0x5ba29ce9) // garbage
  1124. .D32(0x60f20ce6) // saved %ebx
  1125. .D32(0x8036cc02) // garbage
  1126. .Mark(&frame1_esp); // This effectively sets stack_section.start().
  1127. raw_context.eip = 0x40004005;
  1128. raw_context.ebx = 0x53d1379d; // saved %esi
  1129. raw_context.esi = 0x0fb7dc4e; // callee's %esi
  1130. raw_context.edi = 0x40005510; // return address
  1131. CheckWalk();
  1132. }
  1133. TEST_F(CFI, At4006) {
  1134. Label frame0_ebp;
  1135. Label frame1_esp = expected.esp;
  1136. stack_section
  1137. .D32(0xdcdd25cd) // garbage
  1138. .D32(0xafbae234) // saved %edi
  1139. .D32(0xc0d4aab9) // saved %ebp
  1140. .Mark(&frame0_ebp) // frame pointer points here
  1141. .D32(0x60f20ce6) // saved %ebx
  1142. .D32(0x8036cc02) // garbage
  1143. .Mark(&frame1_esp); // This effectively sets stack_section.start().
  1144. raw_context.eip = 0x40004006;
  1145. raw_context.ebp = frame0_ebp.Value();
  1146. raw_context.ebx = 0x53d1379d; // saved %esi
  1147. raw_context.esi = 0x743833c9; // callee's %esi
  1148. raw_context.edi = 0x40005510; // return address
  1149. CheckWalk();
  1150. }