1from intelpt_testcase import * 2from lldbsuite.test.lldbtest import * 3from lldbsuite.test.decorators import * 4 5 6class TestTraceDumpInstructions(TraceIntelPTTestCaseBase): 7 def testErrorMessages(self): 8 # We first check the output when there are no targets 9 self.expect( 10 "thread trace dump instructions", 11 substrs=[ 12 "error: invalid target, create a target using the 'target create' command" 13 ], 14 error=True, 15 ) 16 17 # We now check the output when there's a non-running target 18 self.expect( 19 "target create " 20 + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out") 21 ) 22 23 self.expect( 24 "thread trace dump instructions", 25 substrs=["error: Command requires a current process."], 26 error=True, 27 ) 28 29 # Now we check the output when there's a running target without a trace 30 self.expect("b main") 31 self.expect("run") 32 33 self.expect( 34 "thread trace dump instructions", 35 substrs=["error: Process is not being traced"], 36 error=True, 37 ) 38 39 def testRawDumpInstructionsInJSON(self): 40 self.expect( 41 "trace load -v " 42 + os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"), 43 substrs=["intel-pt"], 44 ) 45 46 self.expect( 47 "thread trace dump instructions --raw --count 5 --forwards --json", 48 substrs=[ 49 """[{"id":3,"loadAddress":"0x400511"}""", 50 """{"id":7,"loadAddress":"0x400518"}""", 51 """{"id":8,"loadAddress":"0x40051f"}""", 52 """{"id":9,"loadAddress":"0x400529"}""", 53 """{"id":10,"loadAddress":"0x40052d"}""", 54 ], 55 ) 56 57 self.expect( 58 "thread trace dump instructions --raw --count 5 --forwards --pretty-json", 59 substrs=[ 60 """[ 61 { 62 "id": 3, 63 "loadAddress": "0x400511" 64 }, 65 { 66 "id": 7, 67 "loadAddress": "0x400518" 68 }, 69 { 70 "id": 8, 71 "loadAddress": "0x40051f" 72 }, 73 { 74 "id": 9, 75 "loadAddress": "0x400529" 76 }, 77 { 78 "id": 10, 79 "loadAddress": "0x40052d" 80 } 81]""" 82 ], 83 ) 84 85 def testRawDumpInstructionsInJSONToFile(self): 86 self.expect( 87 "trace load -v " 88 + os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"), 89 substrs=["intel-pt"], 90 ) 91 92 outfile = os.path.join(self.getBuildDir(), "output.json") 93 94 self.expect( 95 "thread trace dump instructions --raw --count 5 --forwards --pretty-json --file " 96 + outfile 97 ) 98 99 with open(outfile, "r") as out: 100 self.assertEqual( 101 out.read(), 102 """[ 103 { 104 "id": 3, 105 "loadAddress": "0x400511" 106 }, 107 { 108 "id": 7, 109 "loadAddress": "0x400518" 110 }, 111 { 112 "id": 8, 113 "loadAddress": "0x40051f" 114 }, 115 { 116 "id": 9, 117 "loadAddress": "0x400529" 118 }, 119 { 120 "id": 10, 121 "loadAddress": "0x40052d" 122 } 123]""", 124 ) 125 126 def testRawDumpInstructions(self): 127 self.expect( 128 "trace load -v " 129 + os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"), 130 substrs=["intel-pt"], 131 ) 132 133 self.expect( 134 "thread trace dump instructions --raw --count 21 --forwards", 135 substrs=[ 136 """thread #1: tid = 3842849 137 3: 0x0000000000400511 138 7: 0x0000000000400518 139 8: 0x000000000040051f 140 9: 0x0000000000400529 141 10: 0x000000000040052d 142 11: 0x0000000000400521 143 12: 0x0000000000400525 144 13: 0x0000000000400529 145 14: 0x000000000040052d 146 15: 0x0000000000400521 147 16: 0x0000000000400525 148 17: 0x0000000000400529 149 18: 0x000000000040052d 150 19: 0x0000000000400521 151 20: 0x0000000000400525 152 21: 0x0000000000400529 153 22: 0x000000000040052d 154 23: 0x0000000000400521 155 24: 0x0000000000400525 156 25: 0x0000000000400529 157 26: 0x000000000040052""" 158 ], 159 ) 160 161 # We check if we can pass count and skip 162 self.expect( 163 "thread trace dump instructions --count 5 --skip 6 --raw --forwards", 164 substrs=[ 165 """thread #1: tid = 3842849 166 7: 0x0000000000400518 167 8: 0x000000000040051f 168 9: 0x0000000000400529 169 10: 0x000000000040052d 170 11: 0x0000000000400521""" 171 ], 172 ) 173 174 self.expect( 175 "thread trace dump instructions --count 5 --skip 6 --raw", 176 substrs=[ 177 """thread #1: tid = 3842849 178 21: 0x0000000000400529 179 20: 0x0000000000400525 180 19: 0x0000000000400521 181 18: 0x000000000040052d 182 17: 0x0000000000400529""" 183 ], 184 ) 185 186 # We check if we can pass count and skip and instruction id in hex 187 self.expect( 188 "thread trace dump instructions --count 5 --skip 6 --raw --id 0xE", 189 substrs=[ 190 """thread #1: tid = 3842849 191 8: 0x000000000040051f 192 7: 0x0000000000400518 193 3: 0x0000000000400511 194 no more data""" 195 ], 196 ) 197 198 # We check if we can pass count and skip and instruction id in decimal 199 self.expect( 200 "thread trace dump instructions --count 5 --skip 6 --raw --id 14", 201 substrs=[ 202 """thread #1: tid = 3842849 203 8: 0x000000000040051f 204 7: 0x0000000000400518 205 3: 0x0000000000400511 206 no more data""" 207 ], 208 ) 209 210 # We check if we can access the thread by index id 211 self.expect( 212 "thread trace dump instructions 1 --raw", 213 substrs=[ 214 """thread #1: tid = 3842849 215 26: 0x000000000040052d""" 216 ], 217 ) 218 219 # We check that we get an error when using an invalid thread index id 220 self.expect( 221 "thread trace dump instructions 10", 222 error=True, 223 substrs=['error: no thread with index: "10"'], 224 ) 225 226 def testDumpFullInstructionsWithMultipleThreads(self): 227 # We load a trace with two threads 228 self.expect( 229 "trace load -v " 230 + os.path.join(self.getSourceDir(), "intelpt-trace", "trace_2threads.json") 231 ) 232 233 # We print the instructions of a specific thread 234 self.expect( 235 "thread trace dump instructions 2 --count 2", 236 substrs=[ 237 """thread #2: tid = 3842850 238 a.out`main + 32 at main.cpp:4 239 26: 0x000000000040052d jle 0x400521 ; <+20> at main.cpp:5 240 25: 0x0000000000400529 cmpl $0x3, -0x8(%rbp)""" 241 ], 242 ) 243 244 # We use custom --count and --skip, saving the command to history for later 245 self.expect( 246 "thread trace dump instructions 2 --count 2 --skip 2", 247 inHistory=True, 248 substrs=[ 249 """thread #2: tid = 3842850 250 a.out`main + 28 at main.cpp:4 251 25: 0x0000000000400529 cmpl $0x3, -0x8(%rbp) 252 24: 0x0000000000400525 addl $0x1, -0x8(%rbp)""" 253 ], 254 ) 255 256 # We use a repeat command twice and ensure the previous count is used and the 257 # start position moves with each command. 258 self.expect( 259 "", 260 inHistory=True, 261 substrs=[ 262 """thread #2: tid = 3842850 263 a.out`main + 20 at main.cpp:5 264 23: 0x0000000000400521 xorl $0x1, -0x4(%rbp) 265 a.out`main + 32 at main.cpp:4 266 22: 0x000000000040052d jle 0x400521 ; <+20> at main.cpp:5""" 267 ], 268 ) 269 270 self.expect( 271 "", 272 inHistory=True, 273 substrs=[ 274 """thread #2: tid = 3842850 275 a.out`main + 28 at main.cpp:4 276 21: 0x0000000000400529 cmpl $0x3, -0x8(%rbp) 277 20: 0x0000000000400525 addl $0x1, -0x8(%rbp""" 278 ], 279 ) 280 281 def testInvalidBounds(self): 282 self.expect( 283 "trace load -v " 284 + os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json") 285 ) 286 287 # The output should be work when too many instructions are asked 288 self.expect( 289 "thread trace dump instructions --count 20 --forwards", 290 substrs=[ 291 """thread #1: tid = 3842849 292 a.out`main + 4 at main.cpp:2 293 3: 0x0000000000400511 movl $0x0, -0x4(%rbp) 294 a.out`main + 11 at main.cpp:4 295 7: 0x0000000000400518 movl $0x0, -0x8(%rbp) 296 8: 0x000000000040051f jmp 0x400529 ; <+28> at main.cpp:4""" 297 ], 298 ) 299 300 # Should print no instructions if the position is out of bounds 301 self.expect("thread trace dump instructions --skip 23", endstr="no more data\n") 302 303 # Should fail with negative bounds 304 self.expect("thread trace dump instructions --skip -1", error=True) 305 self.expect("thread trace dump instructions --count -1", error=True) 306 307 def testWrongImage(self): 308 self.expect( 309 "trace load " 310 + os.path.join(self.getSourceDir(), "intelpt-trace", "trace_bad_image.json") 311 ) 312 self.expect( 313 "thread trace dump instructions --forwards", 314 substrs=[ 315 """thread #1: tid = 3842849 316 ...missing instructions 317 3: (error) no memory mapped at this address: 0x0000000000400511""" 318 ], 319 ) 320 321 def testWrongCPU(self): 322 self.expect( 323 "trace load " 324 + os.path.join(self.getSourceDir(), "intelpt-trace", "trace_wrong_cpu.json") 325 ) 326 self.expect( 327 "thread trace dump instructions --forwards", 328 substrs=["error: unknown cpu"], 329 error=True, 330 ) 331 332 def testMultiFileTraceWithMissingModuleInJSON(self): 333 self.expect( 334 "trace load " 335 + os.path.join( 336 self.getSourceDir(), "intelpt-trace-multi-file", "multi-file-no-ld.json" 337 ) 338 ) 339 340 self.expect( 341 "thread trace dump instructions --count 4 --id 9 --forwards --pretty-json", 342 substrs=[ 343 """[ 344 { 345 "id": 9, 346 "loadAddress": "0x40054b", 347 "module": "a.out", 348 "symbol": "foo()", 349 "mnemonic": "jmp" 350 }, 351 { 352 "id": 10, 353 "loadAddress": "0x400510", 354 "module": "a.out", 355 "symbol": null, 356 "mnemonic": "pushq" 357 }, 358 { 359 "id": 11, 360 "loadAddress": "0x400516", 361 "module": "a.out", 362 "symbol": null, 363 "mnemonic": "jmpq" 364 }, 365 { 366 "id": 12, 367 "error": "no memory mapped at this address: 0x00007ffff7df1950" 368 }, 369 { 370 "id": 16, 371 "loadAddress": "0x400674", 372 "module": "a.out", 373 "symbol": "main", 374 "mnemonic": "movl", 375 "source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp", 376 "line": 10, 377 "column": 0 378 } 379]""" 380 ], 381 ) 382 383 self.expect( 384 "thread trace dump instructions --count 4 --id 20 --forwards --pretty-json", 385 substrs=[ 386 """[ 387 { 388 "id": 20, 389 "loadAddress": "0x400677", 390 "module": "a.out", 391 "symbol": "main", 392 "mnemonic": "movl", 393 "source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp", 394 "line": 12, 395 "column": 0 396 }, 397 { 398 "id": 21, 399 "loadAddress": "0x40067a", 400 "module": "a.out", 401 "symbol": "main", 402 "mnemonic": "addl", 403 "source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp", 404 "line": 12, 405 "column": 0 406 }, 407 { 408 "id": 22, 409 "loadAddress": "0x40067f", 410 "module": "a.out", 411 "symbol": "main", 412 "mnemonic": "movl", 413 "source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp", 414 "line": 12, 415 "column": 0 416 }, 417 { 418 "id": 26, 419 "loadAddress": "0x400682", 420 "module": "a.out", 421 "symbol": "inline_function()", 422 "mnemonic": "movl", 423 "source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp", 424 "line": 4, 425 "column": 0 426 } 427]""" 428 ], 429 ) 430 431 def testMultiFileTraceWithMissingModule(self): 432 self.expect( 433 "trace load " 434 + os.path.join( 435 self.getSourceDir(), "intelpt-trace-multi-file", "multi-file-no-ld.json" 436 ) 437 ) 438 439 # This instructions in this test covers the following flow: 440 # 441 # - The trace starts with a call to libfoo, which triggers the dynamic 442 # linker, but the dynamic linker is not included in the JSON file, 443 # thus the trace reports a set of missing instructions after 444 # instruction [6]. 445 # - Then, the dump continues in the next synchronization point showing 446 # a call to an inlined function, which is displayed as [inlined]. 447 # - Finally, a call to libfoo is performed, which invokes libbar inside. 448 # 449 # Whenever there's a line or symbol change, including the inline case, a 450 # line is printed showing the symbol context change. 451 # 452 # Finally, the instruction disassembly is included in the dump. 453 self.expect( 454 "thread trace dump instructions --count 50 --forwards", 455 substrs=[ 456 """thread #1: tid = 815455 457 a.out`main + 15 at main.cpp:10 458 3: 0x000000000040066f callq 0x400540 ; symbol stub for: foo() 459 a.out`symbol stub for: foo() 460 7: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40 461 8: 0x0000000000400546 pushq $0x2 462 9: 0x000000000040054b jmp 0x400510 463 a.out`(none) 464 10: 0x0000000000400510 pushq 0x200af2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 8 465 11: 0x0000000000400516 jmpq *0x200af4(%rip) ; _GLOBAL_OFFSET_TABLE_ + 16 466 ...missing instructions 467 12: (error) no memory mapped at this address: 0x00007ffff7df1950 468 a.out`main + 20 at main.cpp:10 469 16: 0x0000000000400674 movl %eax, -0xc(%rbp) 470 a.out`main + 23 at main.cpp:12 471 20: 0x0000000000400677 movl -0xc(%rbp), %eax 472 21: 0x000000000040067a addl $0x1, %eax 473 22: 0x000000000040067f movl %eax, -0xc(%rbp) 474 a.out`main + 34 [inlined] inline_function() at main.cpp:4 475 26: 0x0000000000400682 movl $0x0, -0x4(%rbp) 476 a.out`main + 41 [inlined] inline_function() + 7 at main.cpp:5 477 27: 0x0000000000400689 movl -0x4(%rbp), %eax 478 28: 0x000000000040068c addl $0x1, %eax 479 29: 0x0000000000400691 movl %eax, -0x4(%rbp) 480 a.out`main + 52 [inlined] inline_function() + 18 at main.cpp:6 481 30: 0x0000000000400694 movl -0x4(%rbp), %eax 482 a.out`main + 55 at main.cpp:14 483 31: 0x0000000000400697 movl -0xc(%rbp), %ecx 484 32: 0x000000000040069a addl %eax, %ecx 485 33: 0x000000000040069c movl %ecx, -0xc(%rbp) 486 a.out`main + 63 at main.cpp:16 487 37: 0x000000000040069f callq 0x400540 ; symbol stub for: foo() 488 a.out`symbol stub for: foo() 489 38: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40 490 libfoo.so`foo() at foo.cpp:3 491 39: 0x00007ffff7bd96e0 pushq %rbp 492 40: 0x00007ffff7bd96e1 movq %rsp, %rbp 493 libfoo.so`foo() + 4 at foo.cpp:4 494 41: 0x00007ffff7bd96e4 subq $0x10, %rsp 495 42: 0x00007ffff7bd96e8 callq 0x7ffff7bd95d0 ; symbol stub for: bar() 496 libfoo.so`symbol stub for: bar() 497 43: 0x00007ffff7bd95d0 jmpq *0x200a4a(%rip) ; _GLOBAL_OFFSET_TABLE_ + 32 498 libbar.so`bar() at bar.cpp:1 499 44: 0x00007ffff79d7690 pushq %rbp 500 45: 0x00007ffff79d7691 movq %rsp, %rbp 501 libbar.so`bar() + 4 at bar.cpp:2 502 46: 0x00007ffff79d7694 movl $0x1, -0x4(%rbp) 503 libbar.so`bar() + 11 at bar.cpp:3 504 47: 0x00007ffff79d769b movl -0x4(%rbp), %eax 505 48: 0x00007ffff79d769e addl $0x1, %eax 506 49: 0x00007ffff79d76a3 movl %eax, -0x4(%rbp) 507 libbar.so`bar() + 22 at bar.cpp:4 508 50: 0x00007ffff79d76a6 movl -0x4(%rbp), %eax 509 51: 0x00007ffff79d76a9 popq %rbp 510 52: 0x00007ffff79d76aa retq""", 511 """libfoo.so`foo() + 13 at foo.cpp:4 512 53: 0x00007ffff7bd96ed movl %eax, -0x4(%rbp) 513 libfoo.so`foo() + 16 at foo.cpp:5 514 54: 0x00007ffff7bd96f0 movl -0x4(%rbp), %eax 515 55: 0x00007ffff7bd96f3 addl $0x1, %eax 516 56: 0x00007ffff7bd96f8 movl %eax, -0x4(%rbp) 517 libfoo.so`foo() + 27 at foo.cpp:6 518 57: 0x00007ffff7bd96fb movl -0x4(%rbp), %eax 519 58: 0x00007ffff7bd96fe addq $0x10, %rsp 520 59: 0x00007ffff7bd9702 popq %rbp 521 60: 0x00007ffff7bd9703 retq""", 522 """a.out`main + 68 at main.cpp:16 523 61: 0x00000000004006a4 movl -0xc(%rbp), %ecx 524 62: 0x00000000004006a7 addl %eax, %ecx 525 63: 0x00000000004006a9 movl %ecx, -0xc(%rbp) 526 no more data""", 527 ], 528 ) 529 530 self.expect( 531 "thread trace dump instructions --count 50", 532 substrs=[ 533 """thread #1: tid = 815455 534 a.out`main + 73 at main.cpp:16 535 63: 0x00000000004006a9 movl %ecx, -0xc(%rbp) 536 62: 0x00000000004006a7 addl %eax, %ecx 537 61: 0x00000000004006a4 movl -0xc(%rbp), %ecx 538 libfoo.so`foo() + 35 at foo.cpp:6 539 60: 0x00007ffff7bd9703 retq""", 540 """59: 0x00007ffff7bd9702 popq %rbp 541 58: 0x00007ffff7bd96fe addq $0x10, %rsp 542 57: 0x00007ffff7bd96fb movl -0x4(%rbp), %eax 543 libfoo.so`foo() + 24 at foo.cpp:5 544 56: 0x00007ffff7bd96f8 movl %eax, -0x4(%rbp) 545 55: 0x00007ffff7bd96f3 addl $0x1, %eax 546 54: 0x00007ffff7bd96f0 movl -0x4(%rbp), %eax 547 libfoo.so`foo() + 13 at foo.cpp:4 548 53: 0x00007ffff7bd96ed movl %eax, -0x4(%rbp) 549 libbar.so`bar() + 26 at bar.cpp:4 550 52: 0x00007ffff79d76aa retq""", 551 """51: 0x00007ffff79d76a9 popq %rbp 552 50: 0x00007ffff79d76a6 movl -0x4(%rbp), %eax 553 libbar.so`bar() + 19 at bar.cpp:3 554 49: 0x00007ffff79d76a3 movl %eax, -0x4(%rbp) 555 48: 0x00007ffff79d769e addl $0x1, %eax 556 47: 0x00007ffff79d769b movl -0x4(%rbp), %eax 557 libbar.so`bar() + 4 at bar.cpp:2 558 46: 0x00007ffff79d7694 movl $0x1, -0x4(%rbp) 559 libbar.so`bar() + 1 at bar.cpp:1 560 45: 0x00007ffff79d7691 movq %rsp, %rbp 561 44: 0x00007ffff79d7690 pushq %rbp 562 libfoo.so`symbol stub for: bar() 563 43: 0x00007ffff7bd95d0 jmpq *0x200a4a(%rip) ; _GLOBAL_OFFSET_TABLE_ + 32 564 libfoo.so`foo() + 8 at foo.cpp:4 565 42: 0x00007ffff7bd96e8 callq 0x7ffff7bd95d0 ; symbol stub for: bar() 566 41: 0x00007ffff7bd96e4 subq $0x10, %rsp 567 libfoo.so`foo() + 1 at foo.cpp:3 568 40: 0x00007ffff7bd96e1 movq %rsp, %rbp 569 39: 0x00007ffff7bd96e0 pushq %rbp 570 a.out`symbol stub for: foo() 571 38: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40 572 a.out`main + 63 at main.cpp:16 573 37: 0x000000000040069f callq 0x400540 ; symbol stub for: foo() 574 a.out`main + 60 at main.cpp:14 575 33: 0x000000000040069c movl %ecx, -0xc(%rbp) 576 32: 0x000000000040069a addl %eax, %ecx 577 31: 0x0000000000400697 movl -0xc(%rbp), %ecx 578 a.out`main + 52 [inlined] inline_function() + 18 at main.cpp:6 579 30: 0x0000000000400694 movl -0x4(%rbp), %eax 580 a.out`main + 49 [inlined] inline_function() + 15 at main.cpp:5 581 29: 0x0000000000400691 movl %eax, -0x4(%rbp) 582 28: 0x000000000040068c addl $0x1, %eax 583 27: 0x0000000000400689 movl -0x4(%rbp), %eax 584 a.out`main + 34 [inlined] inline_function() at main.cpp:4 585 26: 0x0000000000400682 movl $0x0, -0x4(%rbp) 586 a.out`main + 31 at main.cpp:12 587 22: 0x000000000040067f movl %eax, -0xc(%rbp) 588 21: 0x000000000040067a addl $0x1, %eax 589 20: 0x0000000000400677 movl -0xc(%rbp), %eax 590 a.out`main + 20 at main.cpp:10 591 16: 0x0000000000400674 movl %eax, -0xc(%rbp) 592 ...missing instructions 593 12: (error) no memory mapped at this address: 0x00007ffff7df1950 594 a.out`(none) 595 11: 0x0000000000400516 jmpq *0x200af4(%rip) ; _GLOBAL_OFFSET_TABLE_ + 16 596 10: 0x0000000000400510 pushq 0x200af2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 8 597 a.out`symbol stub for: foo() + 11 598 9: 0x000000000040054b jmp 0x400510 599 8: 0x0000000000400546 pushq $0x2 600 7: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40 601 a.out`main + 15 at main.cpp:10 602 3: 0x000000000040066f callq 0x400540 ; symbol stub for: foo() 603 no more data""", 604 ], 605 ) 606 607 self.expect( 608 "thread trace dump instructions --skip 100 --forwards", 609 inHistory=True, 610 substrs=[ 611 """thread #1: tid = 815455 612 no more data""" 613 ], 614 ) 615 616 self.expect( 617 "", 618 substrs=[ 619 """thread #1: tid = 815455 620 no more data""" 621 ], 622 ) 623 624 self.expect( 625 "thread trace dump instructions --raw --all --forwards", 626 substrs=[ 627 """thread #1: tid = 815455 628 3: 0x000000000040066f 629 7: 0x0000000000400540""", 630 """11: 0x0000000000400516 631 ...missing instructions 632 12: (error) no memory mapped at this address: 0x00007ffff7df1950 633 16: 0x0000000000400674""", 634 """61: 0x00000000004006a4 635 62: 0x00000000004006a7 636 63: 0x00000000004006a9 637 no more data""", 638 ], 639 ) 640