Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(637)

Side by Side Diff: src/processor/stackwalker_amd64_unittest.cc

Issue 1902783002: Make x86-64 frame pointer unwinding stricter (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/processor/stackwalker_amd64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010, Google Inc. 1 // Copyright (c) 2010, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 using testing::Return; 65 using testing::Return;
66 using testing::SetArgumentPointee; 66 using testing::SetArgumentPointee;
67 using testing::Test; 67 using testing::Test;
68 68
69 class StackwalkerAMD64Fixture { 69 class StackwalkerAMD64Fixture {
70 public: 70 public:
71 StackwalkerAMD64Fixture() 71 StackwalkerAMD64Fixture()
72 : stack_section(kLittleEndian), 72 : stack_section(kLittleEndian),
73 // Give the two modules reasonable standard locations and names 73 // Give the two modules reasonable standard locations and names
74 // for tests to play with. 74 // for tests to play with.
75 module1(0x40000000c0000000ULL, 0x10000, "module1", "version1"), 75 module1(0x00007400c0000000ULL, 0x10000, "module1", "version1"),
76 module2(0x50000000b0000000ULL, 0x10000, "module2", "version2") { 76 module2(0x00007500b0000000ULL, 0x10000, "module2", "version2") {
77 // Identify the system as a Linux system. 77 // Identify the system as a Linux system.
78 system_info.os = "Linux"; 78 system_info.os = "Linux";
79 system_info.os_short = "linux"; 79 system_info.os_short = "linux";
80 system_info.os_version = "Horrendous Hippo"; 80 system_info.os_version = "Horrendous Hippo";
81 system_info.cpu = "x86"; 81 system_info.cpu = "x86";
82 system_info.cpu_info = ""; 82 system_info.cpu_info = "";
83 83
84 // Put distinctive values in the raw CPU context. 84 // Put distinctive values in the raw CPU context.
85 BrandContext(&raw_context); 85 BrandContext(&raw_context);
86 86
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 142
143 class GetContextFrame: public StackwalkerAMD64Fixture, public Test { }; 143 class GetContextFrame: public StackwalkerAMD64Fixture, public Test { };
144 144
145 class SanityCheck: public StackwalkerAMD64Fixture, public Test { }; 145 class SanityCheck: public StackwalkerAMD64Fixture, public Test { };
146 146
147 TEST_F(SanityCheck, NoResolver) { 147 TEST_F(SanityCheck, NoResolver) {
148 // There should be no references to the stack in this walk: we don't 148 // There should be no references to the stack in this walk: we don't
149 // provide any call frame information, so trying to reconstruct the 149 // provide any call frame information, so trying to reconstruct the
150 // context frame's caller should fail. So there's no need for us to 150 // context frame's caller should fail. So there's no need for us to
151 // provide stack contents. 151 // provide stack contents.
152 raw_context.rip = 0x40000000c0000200ULL; 152 raw_context.rip = 0x00007400c0000200ULL;
153 raw_context.rbp = 0x8000000080000000ULL; 153 raw_context.rbp = 0x8000000080000000ULL;
154 154
155 StackFrameSymbolizer frame_symbolizer(NULL, NULL); 155 StackFrameSymbolizer frame_symbolizer(NULL, NULL);
156 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, 156 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
157 &frame_symbolizer); 157 &frame_symbolizer);
158 // This should succeed even without a resolver or supplier. 158 // This should succeed even without a resolver or supplier.
159 vector<const CodeModule*> modules_without_symbols; 159 vector<const CodeModule*> modules_without_symbols;
160 vector<const CodeModule*> modules_with_corrupt_symbols; 160 vector<const CodeModule*> modules_with_corrupt_symbols;
161 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 161 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
162 &modules_with_corrupt_symbols)); 162 &modules_with_corrupt_symbols));
163 ASSERT_EQ(1U, modules_without_symbols.size()); 163 ASSERT_EQ(1U, modules_without_symbols.size());
164 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 164 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
165 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 165 ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
166 frames = call_stack.frames(); 166 frames = call_stack.frames();
167 ASSERT_GE(1U, frames->size()); 167 ASSERT_GE(1U, frames->size());
168 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0)); 168 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0));
169 // Check that the values from the original raw context made it 169 // Check that the values from the original raw context made it
170 // through to the context in the stack frame. 170 // through to the context in the stack frame.
171 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 171 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
172 } 172 }
173 173
174 TEST_F(GetContextFrame, Simple) { 174 TEST_F(GetContextFrame, Simple) {
175 // There should be no references to the stack in this walk: we don't 175 // There should be no references to the stack in this walk: we don't
176 // provide any call frame information, so trying to reconstruct the 176 // provide any call frame information, so trying to reconstruct the
177 // context frame's caller should fail. So there's no need for us to 177 // context frame's caller should fail. So there's no need for us to
178 // provide stack contents. 178 // provide stack contents.
179 raw_context.rip = 0x40000000c0000200ULL; 179 raw_context.rip = 0x00007400c0000200ULL;
180 raw_context.rbp = 0x8000000080000000ULL; 180 raw_context.rbp = 0x8000000080000000ULL;
181 181
182 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 182 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
183 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, 183 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
184 &frame_symbolizer); 184 &frame_symbolizer);
185 vector<const CodeModule*> modules_without_symbols; 185 vector<const CodeModule*> modules_without_symbols;
186 vector<const CodeModule*> modules_with_corrupt_symbols; 186 vector<const CodeModule*> modules_with_corrupt_symbols;
187 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 187 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
188 &modules_with_corrupt_symbols)); 188 &modules_with_corrupt_symbols));
189 ASSERT_EQ(1U, modules_without_symbols.size()); 189 ASSERT_EQ(1U, modules_without_symbols.size());
190 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 190 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
191 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 191 ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
192 frames = call_stack.frames(); 192 frames = call_stack.frames();
193 ASSERT_GE(1U, frames->size()); 193 ASSERT_GE(1U, frames->size());
194 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0)); 194 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0));
195 // Check that the values from the original raw context made it 195 // Check that the values from the original raw context made it
196 // through to the context in the stack frame. 196 // through to the context in the stack frame.
197 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 197 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
198 } 198 }
199 199
200 // The stackwalker should be able to produce the context frame even 200 // The stackwalker should be able to produce the context frame even
201 // without stack memory present. 201 // without stack memory present.
202 TEST_F(GetContextFrame, NoStackMemory) { 202 TEST_F(GetContextFrame, NoStackMemory) {
203 raw_context.rip = 0x40000000c0000200ULL; 203 raw_context.rip = 0x00007400c0000200ULL;
204 raw_context.rbp = 0x8000000080000000ULL; 204 raw_context.rbp = 0x8000000080000000ULL;
205 205
206 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 206 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
207 StackwalkerAMD64 walker(&system_info, &raw_context, NULL, &modules, 207 StackwalkerAMD64 walker(&system_info, &raw_context, NULL, &modules,
208 &frame_symbolizer); 208 &frame_symbolizer);
209 vector<const CodeModule*> modules_without_symbols; 209 vector<const CodeModule*> modules_without_symbols;
210 vector<const CodeModule*> modules_with_corrupt_symbols; 210 vector<const CodeModule*> modules_with_corrupt_symbols;
211 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 211 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
212 &modules_with_corrupt_symbols)); 212 &modules_with_corrupt_symbols));
213 ASSERT_EQ(1U, modules_without_symbols.size()); 213 ASSERT_EQ(1U, modules_without_symbols.size());
214 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file()); 214 ASSERT_EQ("module1", modules_without_symbols[0]->debug_file());
215 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 215 ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
216 frames = call_stack.frames(); 216 frames = call_stack.frames();
217 ASSERT_GE(1U, frames->size()); 217 ASSERT_GE(1U, frames->size());
218 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0)); 218 StackFrameAMD64 *frame = static_cast<StackFrameAMD64 *>(frames->at(0));
219 // Check that the values from the original raw context made it 219 // Check that the values from the original raw context made it
220 // through to the context in the stack frame. 220 // through to the context in the stack frame.
221 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context))); 221 EXPECT_EQ(0, memcmp(&raw_context, &frame->context, sizeof(raw_context)));
222 } 222 }
223 223
224 class GetCallerFrame: public StackwalkerAMD64Fixture, public Test { }; 224 class GetCallerFrame: public StackwalkerAMD64Fixture, public Test { };
225 225
226 TEST_F(GetCallerFrame, ScanWithoutSymbols) { 226 TEST_F(GetCallerFrame, ScanWithoutSymbols) {
227 // When the stack walker resorts to scanning the stack, 227 // When the stack walker resorts to scanning the stack,
228 // only addresses located within loaded modules are 228 // only addresses located within loaded modules are
229 // considered valid return addresses. 229 // considered valid return addresses.
230 // Force scanning through three frames to ensure that the 230 // Force scanning through three frames to ensure that the
231 // stack pointer is set properly in scan-recovered frames. 231 // stack pointer is set properly in scan-recovered frames.
232 stack_section.start() = 0x8000000080000000ULL; 232 stack_section.start() = 0x8000000080000000ULL;
233 uint64_t return_address1 = 0x50000000b0000100ULL; 233 uint64_t return_address1 = 0x00007500b0000100ULL;
234 uint64_t return_address2 = 0x50000000b0000900ULL; 234 uint64_t return_address2 = 0x00007500b0000900ULL;
235 Label frame1_sp, frame2_sp, frame1_rbp; 235 Label frame1_sp, frame2_sp, frame1_rbp;
236 stack_section 236 stack_section
237 // frame 0 237 // frame 0
238 .Append(16, 0) // space 238 .Append(16, 0) // space
239 239
240 .D64(0x40000000b0000000ULL) // junk that's not 240 .D64(0x00007400b0000000ULL) // junk that's not
241 .D64(0x50000000d0000000ULL) // a return address 241 .D64(0x00007500d0000000ULL) // a return address
242 242
243 .D64(return_address1) // actual return address 243 .D64(return_address1) // actual return address
244 // frame 1 244 // frame 1
245 .Mark(&frame1_sp) 245 .Mark(&frame1_sp)
246 .Append(16, 0) // space 246 .Append(16, 0) // space
247 247
248 .D64(0x40000000b0000000ULL) // more junk 248 .D64(0x00007400b0000000ULL) // more junk
249 .D64(0x50000000d0000000ULL) 249 .D64(0x00007500d0000000ULL)
250 250
251 .Mark(&frame1_rbp) 251 .Mark(&frame1_rbp)
252 .D64(stack_section.start()) // This is in the right place to be 252 .D64(stack_section.start()) // This is in the right place to be
253 // a saved rbp, but it's bogus, so 253 // a saved rbp, but it's bogus, so
254 // we shouldn't report it. 254 // we shouldn't report it.
255 255
256 .D64(return_address2) // actual return address 256 .D64(return_address2) // actual return address
257 // frame 2 257 // frame 2
258 .Mark(&frame2_sp) 258 .Mark(&frame2_sp)
259 .Append(32, 0); // end of stack 259 .Append(32, 0); // end of stack
260 260
261 RegionFromSection(); 261 RegionFromSection();
262 262
263 raw_context.rip = 0x40000000c0000200ULL; 263 raw_context.rip = 0x00007400c0000200ULL;
264 raw_context.rbp = frame1_rbp.Value(); 264 raw_context.rbp = frame1_rbp.Value();
265 raw_context.rsp = stack_section.start().Value(); 265 raw_context.rsp = stack_section.start().Value();
266 266
267 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 267 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
268 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, 268 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
269 &frame_symbolizer); 269 &frame_symbolizer);
270 vector<const CodeModule*> modules_without_symbols; 270 vector<const CodeModule*> modules_without_symbols;
271 vector<const CodeModule*> modules_with_corrupt_symbols; 271 vector<const CodeModule*> modules_with_corrupt_symbols;
272 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 272 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
273 &modules_with_corrupt_symbols)); 273 &modules_with_corrupt_symbols));
(...skipping 27 matching lines...) Expand all
301 EXPECT_EQ(return_address2, frame2->context.rip); 301 EXPECT_EQ(return_address2, frame2->context.rip);
302 EXPECT_EQ(frame2_sp.Value(), frame2->context.rsp); 302 EXPECT_EQ(frame2_sp.Value(), frame2->context.rsp);
303 } 303 }
304 304
305 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) { 305 TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
306 // During stack scanning, if a potential return address 306 // During stack scanning, if a potential return address
307 // is located within a loaded module that has symbols, 307 // is located within a loaded module that has symbols,
308 // it is only considered a valid return address if it 308 // it is only considered a valid return address if it
309 // lies within a function's bounds. 309 // lies within a function's bounds.
310 stack_section.start() = 0x8000000080000000ULL; 310 stack_section.start() = 0x8000000080000000ULL;
311 uint64_t return_address = 0x50000000b0000110ULL; 311 uint64_t return_address = 0x00007500b0000110ULL;
312 Label frame1_sp, frame1_rbp; 312 Label frame1_sp, frame1_rbp;
313 313
314 stack_section 314 stack_section
315 // frame 0 315 // frame 0
316 .Append(16, 0) // space 316 .Append(16, 0) // space
317 317
318 .D64(0x40000000b0000000ULL) // junk that's not 318 .D64(0x00007400b0000000ULL) // junk that's not
319 .D64(0x50000000b0000000ULL) // a return address 319 .D64(0x00007500b0000000ULL) // a return address
320 320
321 .D64(0x40000000c0001000ULL) // a couple of plausible addresses 321 .D64(0x00007400c0001000ULL) // a couple of plausible addresses
322 .D64(0x50000000b000aaaaULL) // that are not within functions 322 .D64(0x00007500b000aaaaULL) // that are not within functions
323 323
324 .D64(return_address) // actual return address 324 .D64(return_address) // actual return address
325 // frame 1 325 // frame 1
326 .Mark(&frame1_sp) 326 .Mark(&frame1_sp)
327 .Append(32, 0) // end of stack 327 .Append(32, 0) // end of stack
328 .Mark(&frame1_rbp); 328 .Mark(&frame1_rbp);
329 RegionFromSection(); 329 RegionFromSection();
330 330
331 raw_context.rip = 0x40000000c0000200ULL; 331 raw_context.rip = 0x00007400c0000200ULL;
332 raw_context.rbp = frame1_rbp.Value(); 332 raw_context.rbp = frame1_rbp.Value();
333 raw_context.rsp = stack_section.start().Value(); 333 raw_context.rsp = stack_section.start().Value();
334 334
335 SetModuleSymbols(&module1, 335 SetModuleSymbols(&module1,
336 // The youngest frame's function. 336 // The youngest frame's function.
337 "FUNC 100 400 10 platypus\n"); 337 "FUNC 100 400 10 platypus\n");
338 SetModuleSymbols(&module2, 338 SetModuleSymbols(&module2,
339 // The calling frame's function. 339 // The calling frame's function.
340 "FUNC 100 400 10 echidna\n"); 340 "FUNC 100 400 10 echidna\n");
341 341
342 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 342 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
343 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, 343 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
344 &frame_symbolizer); 344 &frame_symbolizer);
345 vector<const CodeModule*> modules_without_symbols; 345 vector<const CodeModule*> modules_without_symbols;
346 vector<const CodeModule*> modules_with_corrupt_symbols; 346 vector<const CodeModule*> modules_with_corrupt_symbols;
347 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 347 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
348 &modules_with_corrupt_symbols)); 348 &modules_with_corrupt_symbols));
349 ASSERT_EQ(0U, modules_without_symbols.size()); 349 ASSERT_EQ(0U, modules_without_symbols.size());
350 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 350 ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
351 frames = call_stack.frames(); 351 frames = call_stack.frames();
352 ASSERT_EQ(2U, frames->size()); 352 ASSERT_EQ(2U, frames->size());
353 353
354 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0)); 354 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0));
355 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 355 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
356 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); 356 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
357 EXPECT_EQ("platypus", frame0->function_name); 357 EXPECT_EQ("platypus", frame0->function_name);
358 EXPECT_EQ(0x40000000c0000100ULL, frame0->function_base); 358 EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base);
359 359
360 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1)); 360 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
361 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust); 361 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
362 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | 362 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
363 StackFrameAMD64::CONTEXT_VALID_RSP | 363 StackFrameAMD64::CONTEXT_VALID_RSP |
364 StackFrameAMD64::CONTEXT_VALID_RBP), 364 StackFrameAMD64::CONTEXT_VALID_RBP),
365 frame1->context_validity); 365 frame1->context_validity);
366 EXPECT_EQ(return_address, frame1->context.rip); 366 EXPECT_EQ(return_address, frame1->context.rip);
367 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); 367 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
368 EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp); 368 EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
369 EXPECT_EQ("echidna", frame1->function_name); 369 EXPECT_EQ("echidna", frame1->function_name);
370 EXPECT_EQ(0x50000000b0000100ULL, frame1->function_base); 370 EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base);
371 } 371 }
372 372
373 // StackwalkerAMD64::GetCallerByFramePointerRecovery should never return an 373 // StackwalkerAMD64::GetCallerByFramePointerRecovery should never return an
374 // instruction pointer of 0 because IP of 0 is an end of stack marker and the 374 // instruction pointer of 0 because IP of 0 is an end of stack marker and the
375 // stack walk may be terminated prematurely. Instead it should return NULL 375 // stack walk may be terminated prematurely. Instead it should return NULL
376 // so that the stack walking code can proceed to stack scanning. 376 // so that the stack walking code can proceed to stack scanning.
377 TEST_F(GetCallerFrame, GetCallerByFramePointerRecovery) { 377 TEST_F(GetCallerFrame, GetCallerByFramePointerRecovery) {
378 MockCodeModule user32_dll(0x00007ff9cb8a0000ULL, 0x14E000, "user32.dll", 378 MockCodeModule user32_dll(0x00007ff9cb8a0000ULL, 0x14E000, "user32.dll",
379 "version1"); 379 "version1");
380 SetModuleSymbols(&user32_dll, // user32.dll 380 SetModuleSymbols(&user32_dll, // user32.dll
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 StackFrameAMD64::CONTEXT_VALID_RBP), 495 StackFrameAMD64::CONTEXT_VALID_RBP),
496 frame->context_validity); 496 frame->context_validity);
497 EXPECT_EQ("DispatchMessageWorker", frame->function_name); 497 EXPECT_EQ("DispatchMessageWorker", frame->function_name);
498 EXPECT_EQ(140710838467591ULL, frame->instruction + 1); 498 EXPECT_EQ(140710838467591ULL, frame->instruction + 1);
499 EXPECT_EQ(140710838467591ULL, frame->context.rip); 499 EXPECT_EQ(140710838467591ULL, frame->context.rip);
500 EXPECT_EQ(frame2_rsp.Value(), frame->context.rsp); 500 EXPECT_EQ(frame2_rsp.Value(), frame->context.rsp);
501 EXPECT_EQ(&user32_dll, frame->module); 501 EXPECT_EQ(&user32_dll, frame->module);
502 } 502 }
503 } 503 }
504 504
505 // Don't use frame pointer recovery if %rbp is not 8-byte aligned, which
506 // indicates that it's not being used as a frame pointer.
507 TEST_F(GetCallerFrame, FramePointerNotAligned) {
508 stack_section.start() = 0x8000000080000000ULL;
509 uint64_t return_address1 = 0x00007500b0000100ULL;
510 Label frame0_rbp, not_frame1_rbp, frame1_sp;
511 stack_section
512 // frame 0
513 .Align(8, 0)
514 .Append(2, 0) // mis-align the frame pointer
515 .Mark(&frame0_rbp)
516 .D64(not_frame1_rbp) // not the previous frame pointer
517 .D64(0x00007500b0000a00ULL) // plausible but wrong return address
518 .Align(8, 0)
519 .D64(return_address1) // return address
520 // frame 1
521 .Mark(&frame1_sp)
522 .Mark(&not_frame1_rbp)
523 .Append(32, 0); // end of stack
524
525
526 RegionFromSection();
527
528 raw_context.rip = 0x00007400c0000200ULL;
529 raw_context.rbp = frame0_rbp.Value();
530 raw_context.rsp = stack_section.start().Value();
531
532 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
533 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
534 &frame_symbolizer);
535 vector<const CodeModule*> modules_without_symbols;
536 vector<const CodeModule*> modules_with_corrupt_symbols;
537 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
538 &modules_with_corrupt_symbols));
539 frames = call_stack.frames();
540 ASSERT_EQ(2U, frames->size());
541
542 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0));
543 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
544 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
545 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
546
547 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
548 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
549 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
550 StackFrameAMD64::CONTEXT_VALID_RSP),
551 frame1->context_validity);
552 EXPECT_EQ(return_address1, frame1->context.rip);
553 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
554 }
555
556 // Don't use frame pointer recovery if the recovered %rip is not
557 // a canonical x86-64 address.
558 TEST_F(GetCallerFrame, NonCanonicalInstructionPointerFromFramePointer) {
559 stack_section.start() = 0x8000000080000000ULL;
560 uint64_t return_address1 = 0x00007500b0000100ULL;
561 Label frame0_rbp, frame1_sp, not_frame1_bp;
562 stack_section
563 // frame 0
564 .Align(8, 0)
565 .Mark(&frame0_rbp)
566 .D64(not_frame1_bp) // some junk on the stack
567 .D64(0xDADADADADADADADA) // not the return address
568 .D64(return_address1) // return address
569 // frame 1
570 .Mark(&frame1_sp)
571 .Append(16, 0)
572 .Mark(&not_frame1_bp)
573 .Append(32, 0); // end of stack
574
575
576 RegionFromSection();
577
578 raw_context.rip = 0x00007400c0000200ULL;
579 raw_context.rbp = frame0_rbp.Value();
580 raw_context.rsp = stack_section.start().Value();
581
582 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
583 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
584 &frame_symbolizer);
585 vector<const CodeModule*> modules_without_symbols;
586 vector<const CodeModule*> modules_with_corrupt_symbols;
587 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
588 &modules_with_corrupt_symbols));
589 frames = call_stack.frames();
590 ASSERT_EQ(2U, frames->size());
591
592 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0));
593 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
594 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
595 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
596
597 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
598 EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
599 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
600 StackFrameAMD64::CONTEXT_VALID_RSP),
601 frame1->context_validity);
602 EXPECT_EQ(return_address1, frame1->context.rip);
603 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
604 }
605
505 // Test that set_max_frames_scanned prevents using stack scanning 606 // Test that set_max_frames_scanned prevents using stack scanning
506 // to find caller frames. 607 // to find caller frames.
507 TEST_F(GetCallerFrame, ScanningNotAllowed) { 608 TEST_F(GetCallerFrame, ScanningNotAllowed) {
508 // When the stack walker resorts to scanning the stack, 609 // When the stack walker resorts to scanning the stack,
509 // only addresses located within loaded modules are 610 // only addresses located within loaded modules are
510 // considered valid return addresses. 611 // considered valid return addresses.
511 stack_section.start() = 0x8000000080000000ULL; 612 stack_section.start() = 0x8000000080000000ULL;
512 uint64_t return_address1 = 0x50000000b0000100ULL; 613 uint64_t return_address1 = 0x00007500b0000100ULL;
513 uint64_t return_address2 = 0x50000000b0000900ULL; 614 uint64_t return_address2 = 0x00007500b0000900ULL;
514 Label frame1_sp, frame2_sp, frame1_rbp; 615 Label frame1_sp, frame2_sp, frame1_rbp;
515 stack_section 616 stack_section
516 // frame 0 617 // frame 0
517 .Append(16, 0) // space 618 .Append(16, 0) // space
518 619
519 .D64(0x40000000b0000000ULL) // junk that's not 620 .D64(0x00007400b0000000ULL) // junk that's not
520 .D64(0x50000000d0000000ULL) // a return address 621 .D64(0x00007500d0000000ULL) // a return address
521 622
522 .D64(return_address1) // actual return address 623 .D64(return_address1) // actual return address
523 // frame 1 624 // frame 1
524 .Mark(&frame1_sp) 625 .Mark(&frame1_sp)
525 .Append(16, 0) // space 626 .Append(16, 0) // space
526 627
527 .D64(0x40000000b0000000ULL) // more junk 628 .D64(0x00007400b0000000ULL) // more junk
528 .D64(0x50000000d0000000ULL) 629 .D64(0x00007500d0000000ULL)
529 630
530 .Mark(&frame1_rbp) 631 .Mark(&frame1_rbp)
531 .D64(stack_section.start()) // This is in the right place to be 632 .D64(stack_section.start()) // This is in the right place to be
532 // a saved rbp, but it's bogus, so 633 // a saved rbp, but it's bogus, so
533 // we shouldn't report it. 634 // we shouldn't report it.
534 635
535 .D64(return_address2) // actual return address 636 .D64(return_address2) // actual return address
536 // frame 2 637 // frame 2
537 .Mark(&frame2_sp) 638 .Mark(&frame2_sp)
538 .Append(32, 0); // end of stack 639 .Append(32, 0); // end of stack
539 640
540 RegionFromSection(); 641 RegionFromSection();
541 642
542 raw_context.rip = 0x40000000c0000200ULL; 643 raw_context.rip = 0x00007400c0000200ULL;
543 raw_context.rbp = frame1_rbp.Value(); 644 raw_context.rbp = frame1_rbp.Value();
544 raw_context.rsp = stack_section.start().Value(); 645 raw_context.rsp = stack_section.start().Value();
545 646
546 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 647 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
547 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, 648 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
548 &frame_symbolizer); 649 &frame_symbolizer);
549 Stackwalker::set_max_frames_scanned(0); 650 Stackwalker::set_max_frames_scanned(0);
550 651
551 vector<const CodeModule*> modules_without_symbols; 652 vector<const CodeModule*> modules_without_symbols;
552 vector<const CodeModule*> modules_with_corrupt_symbols; 653 vector<const CodeModule*> modules_with_corrupt_symbols;
(...skipping 10 matching lines...) Expand all
563 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); 664 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
564 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context))); 665 EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
565 } 666 }
566 667
567 TEST_F(GetCallerFrame, CallerPushedRBP) { 668 TEST_F(GetCallerFrame, CallerPushedRBP) {
568 // Functions typically push their %rbp upon entry and set %rbp pointing 669 // Functions typically push their %rbp upon entry and set %rbp pointing
569 // there. If stackwalking finds a plausible address for the next frame's 670 // there. If stackwalking finds a plausible address for the next frame's
570 // %rbp directly below the return address, assume that it is indeed the 671 // %rbp directly below the return address, assume that it is indeed the
571 // next frame's %rbp. 672 // next frame's %rbp.
572 stack_section.start() = 0x8000000080000000ULL; 673 stack_section.start() = 0x8000000080000000ULL;
573 uint64_t return_address = 0x50000000b0000110ULL; 674 uint64_t return_address = 0x00007500b0000110ULL;
574 Label frame0_rbp, frame1_sp, frame1_rbp; 675 Label frame0_rbp, frame1_sp, frame1_rbp;
575 676
576 stack_section 677 stack_section
577 // frame 0 678 // frame 0
578 .Append(16, 0) // space 679 .Append(16, 0) // space
579 680
580 .D64(0x40000000b0000000ULL) // junk that's not 681 .D64(0x00007400b0000000ULL) // junk that's not
581 .D64(0x50000000b0000000ULL) // a return address 682 .D64(0x00007500b0000000ULL) // a return address
582 683
583 .D64(0x40000000c0001000ULL) // a couple of plausible addresses 684 .D64(0x00007400c0001000ULL) // a couple of plausible addresses
584 .D64(0x50000000b000aaaaULL) // that are not within functions 685 .D64(0x00007500b000aaaaULL) // that are not within functions
585 686
586 .Mark(&frame0_rbp) 687 .Mark(&frame0_rbp)
587 .D64(frame1_rbp) // caller-pushed %rbp 688 .D64(frame1_rbp) // caller-pushed %rbp
588 .D64(return_address) // actual return address 689 .D64(return_address) // actual return address
589 // frame 1 690 // frame 1
590 .Mark(&frame1_sp) 691 .Mark(&frame1_sp)
591 .Append(32, 0) // body of frame1 692 .Append(32, 0) // body of frame1
592 .Mark(&frame1_rbp); // end of stack 693 .Mark(&frame1_rbp); // end of stack
593 RegionFromSection(); 694 RegionFromSection();
594 695
595 raw_context.rip = 0x40000000c0000200ULL; 696 raw_context.rip = 0x00007400c0000200ULL;
596 raw_context.rbp = frame0_rbp.Value(); 697 raw_context.rbp = frame0_rbp.Value();
597 raw_context.rsp = stack_section.start().Value(); 698 raw_context.rsp = stack_section.start().Value();
598 699
599 SetModuleSymbols(&module1, 700 SetModuleSymbols(&module1,
600 // The youngest frame's function. 701 // The youngest frame's function.
601 "FUNC 100 400 10 sasquatch\n"); 702 "FUNC 100 400 10 sasquatch\n");
602 SetModuleSymbols(&module2, 703 SetModuleSymbols(&module2,
603 // The calling frame's function. 704 // The calling frame's function.
604 "FUNC 100 400 10 yeti\n"); 705 "FUNC 100 400 10 yeti\n");
605 706
606 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver); 707 StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
607 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules, 708 StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
608 &frame_symbolizer); 709 &frame_symbolizer);
609 vector<const CodeModule*> modules_without_symbols; 710 vector<const CodeModule*> modules_without_symbols;
610 vector<const CodeModule*> modules_with_corrupt_symbols; 711 vector<const CodeModule*> modules_with_corrupt_symbols;
611 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols, 712 ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
612 &modules_with_corrupt_symbols)); 713 &modules_with_corrupt_symbols));
613 ASSERT_EQ(0U, modules_without_symbols.size()); 714 ASSERT_EQ(0U, modules_without_symbols.size());
614 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 715 ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
615 frames = call_stack.frames(); 716 frames = call_stack.frames();
616 ASSERT_EQ(2U, frames->size()); 717 ASSERT_EQ(2U, frames->size());
617 718
618 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0)); 719 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0));
619 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 720 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
620 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); 721 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
621 EXPECT_EQ(frame0_rbp.Value(), frame0->context.rbp); 722 EXPECT_EQ(frame0_rbp.Value(), frame0->context.rbp);
622 EXPECT_EQ("sasquatch", frame0->function_name); 723 EXPECT_EQ("sasquatch", frame0->function_name);
623 EXPECT_EQ(0x40000000c0000100ULL, frame0->function_base); 724 EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base);
624 725
625 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1)); 726 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
626 EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust); 727 EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
627 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | 728 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
628 StackFrameAMD64::CONTEXT_VALID_RSP | 729 StackFrameAMD64::CONTEXT_VALID_RSP |
629 StackFrameAMD64::CONTEXT_VALID_RBP), 730 StackFrameAMD64::CONTEXT_VALID_RBP),
630 frame1->context_validity); 731 frame1->context_validity);
631 EXPECT_EQ(return_address, frame1->context.rip); 732 EXPECT_EQ(return_address, frame1->context.rip);
632 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp); 733 EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
633 EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp); 734 EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
634 EXPECT_EQ("yeti", frame1->function_name); 735 EXPECT_EQ("yeti", frame1->function_name);
635 EXPECT_EQ(0x50000000b0000100ULL, frame1->function_base); 736 EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base);
636 } 737 }
637 738
638 struct CFIFixture: public StackwalkerAMD64Fixture { 739 struct CFIFixture: public StackwalkerAMD64Fixture {
639 CFIFixture() { 740 CFIFixture() {
640 // Provide a bunch of STACK CFI records; we'll walk to the caller 741 // Provide a bunch of STACK CFI records; we'll walk to the caller
641 // from every point in this series, expecting to find the same set 742 // from every point in this series, expecting to find the same set
642 // of register values. 743 // of register values.
643 SetModuleSymbols(&module1, 744 SetModuleSymbols(&module1,
644 // The youngest frame's function. 745 // The youngest frame's function.
645 "FUNC 4000 1000 10 enchiridion\n" 746 "FUNC 4000 1000 10 enchiridion\n"
(...skipping 10 matching lines...) Expand all
656 // Save %rbp, and use it as a frame pointer. 757 // Save %rbp, and use it as a frame pointer.
657 "STACK CFI 4006 .cfa: $rbp 16 + $rbp: .cfa 24 - ^\n" 758 "STACK CFI 4006 .cfa: $rbp 16 + $rbp: .cfa 24 - ^\n"
658 759
659 // The calling function. 760 // The calling function.
660 "FUNC 5000 1000 10 epictetus\n" 761 "FUNC 5000 1000 10 epictetus\n"
661 // Mark it as end of stack. 762 // Mark it as end of stack.
662 "STACK CFI INIT 5000 1000 .cfa: $rsp .ra 0\n"); 763 "STACK CFI INIT 5000 1000 .cfa: $rsp .ra 0\n");
663 764
664 // Provide some distinctive values for the caller's registers. 765 // Provide some distinctive values for the caller's registers.
665 expected.rsp = 0x8000000080000000ULL; 766 expected.rsp = 0x8000000080000000ULL;
666 expected.rip = 0x40000000c0005510ULL; 767 expected.rip = 0x00007400c0005510ULL;
667 expected.rbp = 0x68995b1de4700266ULL; 768 expected.rbp = 0x68995b1de4700266ULL;
668 expected.rbx = 0x5a5beeb38de23be8ULL; 769 expected.rbx = 0x5a5beeb38de23be8ULL;
669 expected.r12 = 0xed1b02e8cc0fc79cULL; 770 expected.r12 = 0xed1b02e8cc0fc79cULL;
670 expected.r13 = 0x1d20ad8acacbe930ULL; 771 expected.r13 = 0x1d20ad8acacbe930ULL;
671 expected.r14 = 0xe94cffc2f7adaa28ULL; 772 expected.r14 = 0xe94cffc2f7adaa28ULL;
672 expected.r15 = 0xb638d17d8da413b5ULL; 773 expected.r15 = 0xb638d17d8da413b5ULL;
673 774
674 // By default, registers are unchanged. 775 // By default, registers are unchanged.
675 raw_context = expected; 776 raw_context = expected;
676 } 777 }
(...skipping 16 matching lines...) Expand all
693 &modules_with_corrupt_symbols)); 794 &modules_with_corrupt_symbols));
694 ASSERT_EQ(0U, modules_without_symbols.size()); 795 ASSERT_EQ(0U, modules_without_symbols.size());
695 ASSERT_EQ(0U, modules_with_corrupt_symbols.size()); 796 ASSERT_EQ(0U, modules_with_corrupt_symbols.size());
696 frames = call_stack.frames(); 797 frames = call_stack.frames();
697 ASSERT_EQ(2U, frames->size()); 798 ASSERT_EQ(2U, frames->size());
698 799
699 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0)); 800 StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0));
700 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust); 801 EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
701 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity); 802 ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
702 EXPECT_EQ("enchiridion", frame0->function_name); 803 EXPECT_EQ("enchiridion", frame0->function_name);
703 EXPECT_EQ(0x40000000c0004000ULL, frame0->function_base); 804 EXPECT_EQ(0x00007400c0004000ULL, frame0->function_base);
704 805
705 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1)); 806 StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
706 EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust); 807 EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
707 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP | 808 ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
708 StackFrameAMD64::CONTEXT_VALID_RSP | 809 StackFrameAMD64::CONTEXT_VALID_RSP |
709 StackFrameAMD64::CONTEXT_VALID_RBP | 810 StackFrameAMD64::CONTEXT_VALID_RBP |
710 StackFrameAMD64::CONTEXT_VALID_RBX | 811 StackFrameAMD64::CONTEXT_VALID_RBX |
711 StackFrameAMD64::CONTEXT_VALID_R12 | 812 StackFrameAMD64::CONTEXT_VALID_R12 |
712 StackFrameAMD64::CONTEXT_VALID_R13 | 813 StackFrameAMD64::CONTEXT_VALID_R13 |
713 StackFrameAMD64::CONTEXT_VALID_R14 | 814 StackFrameAMD64::CONTEXT_VALID_R14 |
(...skipping 12 matching lines...) Expand all
726 827
727 // The values we expect to find for the caller's registers. 828 // The values we expect to find for the caller's registers.
728 MDRawContextAMD64 expected; 829 MDRawContextAMD64 expected;
729 }; 830 };
730 831
731 class CFI: public CFIFixture, public Test { }; 832 class CFI: public CFIFixture, public Test { };
732 833
733 TEST_F(CFI, At4000) { 834 TEST_F(CFI, At4000) {
734 Label frame1_rsp = expected.rsp; 835 Label frame1_rsp = expected.rsp;
735 stack_section 836 stack_section
736 .D64(0x40000000c0005510ULL) // return address 837 .D64(0x00007400c0005510ULL) // return address
737 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 838 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
738 raw_context.rip = 0x40000000c0004000ULL; 839 raw_context.rip = 0x00007400c0004000ULL;
739 CheckWalk(); 840 CheckWalk();
740 } 841 }
741 842
742 TEST_F(CFI, At4001) { 843 TEST_F(CFI, At4001) {
743 Label frame1_rsp = expected.rsp; 844 Label frame1_rsp = expected.rsp;
744 stack_section 845 stack_section
745 .D64(0x5a5beeb38de23be8ULL) // saved %rbx 846 .D64(0x5a5beeb38de23be8ULL) // saved %rbx
746 .D64(0x40000000c0005510ULL) // return address 847 .D64(0x00007400c0005510ULL) // return address
747 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 848 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
748 raw_context.rip = 0x40000000c0004001ULL; 849 raw_context.rip = 0x00007400c0004001ULL;
749 raw_context.rbx = 0xbe0487d2f9eafe29ULL; // callee's (distinct) %rbx value 850 raw_context.rbx = 0xbe0487d2f9eafe29ULL; // callee's (distinct) %rbx value
750 CheckWalk(); 851 CheckWalk();
751 } 852 }
752 853
753 TEST_F(CFI, At4002) { 854 TEST_F(CFI, At4002) {
754 Label frame1_rsp = expected.rsp; 855 Label frame1_rsp = expected.rsp;
755 stack_section 856 stack_section
756 .D64(0x5a5beeb38de23be8ULL) // saved %rbx 857 .D64(0x5a5beeb38de23be8ULL) // saved %rbx
757 .D64(0x40000000c0005510ULL) // return address 858 .D64(0x00007400c0005510ULL) // return address
758 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 859 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
759 raw_context.rip = 0x40000000c0004002ULL; 860 raw_context.rip = 0x00007400c0004002ULL;
760 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 861 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
761 raw_context.r12 = 0xb0118de918a4bceaULL; // callee's (distinct) %r12 value 862 raw_context.r12 = 0xb0118de918a4bceaULL; // callee's (distinct) %r12 value
762 CheckWalk(); 863 CheckWalk();
763 } 864 }
764 865
765 TEST_F(CFI, At4003) { 866 TEST_F(CFI, At4003) {
766 Label frame1_rsp = expected.rsp; 867 Label frame1_rsp = expected.rsp;
767 stack_section 868 stack_section
768 .D64(0x0e023828dffd4d81ULL) // garbage 869 .D64(0x0e023828dffd4d81ULL) // garbage
769 .D64(0x1d20ad8acacbe930ULL) // saved %r13 870 .D64(0x1d20ad8acacbe930ULL) // saved %r13
770 .D64(0x319e68b49e3ace0fULL) // garbage 871 .D64(0x319e68b49e3ace0fULL) // garbage
771 .D64(0x5a5beeb38de23be8ULL) // saved %rbx 872 .D64(0x5a5beeb38de23be8ULL) // saved %rbx
772 .D64(0x40000000c0005510ULL) // return address 873 .D64(0x00007400c0005510ULL) // return address
773 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 874 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
774 raw_context.rip = 0x40000000c0004003ULL; 875 raw_context.rip = 0x00007400c0004003ULL;
775 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 876 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
776 raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12 877 raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12
777 raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13 878 raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13
778 CheckWalk(); 879 CheckWalk();
779 } 880 }
780 881
781 // The results here should be the same as those at module offset 0x4003. 882 // The results here should be the same as those at module offset 0x4003.
782 TEST_F(CFI, At4004) { 883 TEST_F(CFI, At4004) {
783 Label frame1_rsp = expected.rsp; 884 Label frame1_rsp = expected.rsp;
784 stack_section 885 stack_section
785 .D64(0x0e023828dffd4d81ULL) // garbage 886 .D64(0x0e023828dffd4d81ULL) // garbage
786 .D64(0x1d20ad8acacbe930ULL) // saved %r13 887 .D64(0x1d20ad8acacbe930ULL) // saved %r13
787 .D64(0x319e68b49e3ace0fULL) // garbage 888 .D64(0x319e68b49e3ace0fULL) // garbage
788 .D64(0x5a5beeb38de23be8ULL) // saved %rbx 889 .D64(0x5a5beeb38de23be8ULL) // saved %rbx
789 .D64(0x40000000c0005510ULL) // return address 890 .D64(0x00007400c0005510ULL) // return address
790 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 891 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
791 raw_context.rip = 0x40000000c0004004ULL; 892 raw_context.rip = 0x00007400c0004004ULL;
792 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 893 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
793 raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12 894 raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12
794 raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13 895 raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13
795 CheckWalk(); 896 CheckWalk();
796 } 897 }
797 898
798 TEST_F(CFI, At4005) { 899 TEST_F(CFI, At4005) {
799 Label frame1_rsp = expected.rsp; 900 Label frame1_rsp = expected.rsp;
800 stack_section 901 stack_section
801 .D64(0x4b516dd035745953ULL) // garbage 902 .D64(0x4b516dd035745953ULL) // garbage
802 .D64(0x1d20ad8acacbe930ULL) // saved %r13 903 .D64(0x1d20ad8acacbe930ULL) // saved %r13
803 .D64(0xa6d445e16ae3d872ULL) // garbage 904 .D64(0xa6d445e16ae3d872ULL) // garbage
804 .D64(0x5a5beeb38de23be8ULL) // saved %rbx 905 .D64(0x5a5beeb38de23be8ULL) // saved %rbx
805 .D64(0xaa95fa054aedfbaeULL) // garbage 906 .D64(0xaa95fa054aedfbaeULL) // garbage
806 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 907 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
807 raw_context.rip = 0x40000000c0004005ULL; 908 raw_context.rip = 0x00007400c0004005ULL;
808 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 909 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
809 raw_context.r12 = 0x46b1b8868891b34aULL; // callee's %r12 910 raw_context.r12 = 0x46b1b8868891b34aULL; // callee's %r12
810 raw_context.r13 = 0x40000000c0005510ULL; // return address 911 raw_context.r13 = 0x00007400c0005510ULL; // return address
811 CheckWalk(); 912 CheckWalk();
812 } 913 }
813 914
814 TEST_F(CFI, At4006) { 915 TEST_F(CFI, At4006) {
815 Label frame0_rbp; 916 Label frame0_rbp;
816 Label frame1_rsp = expected.rsp; 917 Label frame1_rsp = expected.rsp;
817 stack_section 918 stack_section
818 .D64(0x043c6dfceb91aa34ULL) // garbage 919 .D64(0x043c6dfceb91aa34ULL) // garbage
819 .D64(0x1d20ad8acacbe930ULL) // saved %r13 920 .D64(0x1d20ad8acacbe930ULL) // saved %r13
820 .D64(0x68995b1de4700266ULL) // saved %rbp 921 .D64(0x68995b1de4700266ULL) // saved %rbp
821 .Mark(&frame0_rbp) // frame pointer points here 922 .Mark(&frame0_rbp) // frame pointer points here
822 .D64(0x5a5beeb38de23be8ULL) // saved %rbx 923 .D64(0x5a5beeb38de23be8ULL) // saved %rbx
823 .D64(0xf015ee516ad89eabULL) // garbage 924 .D64(0xf015ee516ad89eabULL) // garbage
824 .Mark(&frame1_rsp); // This effectively sets stack_section.start(). 925 .Mark(&frame1_rsp); // This effectively sets stack_section.start().
825 raw_context.rip = 0x40000000c0004006ULL; 926 raw_context.rip = 0x00007400c0004006ULL;
826 raw_context.rbp = frame0_rbp.Value(); 927 raw_context.rbp = frame0_rbp.Value();
827 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12 928 raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
828 raw_context.r12 = 0x26e007b341acfebdULL; // callee's %r12 929 raw_context.r12 = 0x26e007b341acfebdULL; // callee's %r12
829 raw_context.r13 = 0x40000000c0005510ULL; // return address 930 raw_context.r13 = 0x00007400c0005510ULL; // return address
830 CheckWalk(); 931 CheckWalk();
831 } 932 }
OLDNEW
« no previous file with comments | « src/processor/stackwalker_amd64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698