510 lines
19 KiB
Python
510 lines
19 KiB
Python
from intelpt_testcase import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test.decorators import *
|
|
|
|
class TestTraceDumpInstructions(TraceIntelPTTestCaseBase):
|
|
|
|
def testErrorMessages(self):
|
|
# We first check the output when there are no targets
|
|
self.expect("thread trace dump instructions",
|
|
substrs=["error: invalid target, create a target using the 'target create' command"],
|
|
error=True)
|
|
|
|
# We now check the output when there's a non-running target
|
|
self.expect("target create " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
|
|
|
|
self.expect("thread trace dump instructions",
|
|
substrs=["error: Command requires a current process."],
|
|
error=True)
|
|
|
|
# Now we check the output when there's a running target without a trace
|
|
self.expect("b main")
|
|
self.expect("run")
|
|
|
|
self.expect("thread trace dump instructions",
|
|
substrs=["error: Process is not being traced"],
|
|
error=True)
|
|
|
|
def testRawDumpInstructionsInJSON(self):
|
|
self.expect("trace load -v " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
|
|
substrs=["intel-pt"])
|
|
|
|
self.expect("thread trace dump instructions --raw --count 5 --forwards --json",
|
|
substrs=['''[{"id":3,"loadAddress":"0x400511"}''',
|
|
'''{"id":7,"loadAddress":"0x400518"}''',
|
|
'''{"id":8,"loadAddress":"0x40051f"}''',
|
|
'''{"id":9,"loadAddress":"0x400529"}''',
|
|
'''{"id":10,"loadAddress":"0x40052d"}'''])
|
|
|
|
self.expect("thread trace dump instructions --raw --count 5 --forwards --pretty-json",
|
|
substrs=['''[
|
|
{
|
|
"id": 3,
|
|
"loadAddress": "0x400511"
|
|
},
|
|
{
|
|
"id": 7,
|
|
"loadAddress": "0x400518"
|
|
},
|
|
{
|
|
"id": 8,
|
|
"loadAddress": "0x40051f"
|
|
},
|
|
{
|
|
"id": 9,
|
|
"loadAddress": "0x400529"
|
|
},
|
|
{
|
|
"id": 10,
|
|
"loadAddress": "0x40052d"
|
|
}
|
|
]'''])
|
|
|
|
def testRawDumpInstructionsInJSONToFile(self):
|
|
self.expect("trace load -v " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
|
|
substrs=["intel-pt"])
|
|
|
|
outfile = os.path.join(self.getBuildDir(), "output.json")
|
|
|
|
self.expect("thread trace dump instructions --raw --count 5 --forwards --pretty-json --file " + outfile)
|
|
|
|
with open(outfile, "r") as out:
|
|
self.assertEqual(out.read(), '''[
|
|
{
|
|
"id": 3,
|
|
"loadAddress": "0x400511"
|
|
},
|
|
{
|
|
"id": 7,
|
|
"loadAddress": "0x400518"
|
|
},
|
|
{
|
|
"id": 8,
|
|
"loadAddress": "0x40051f"
|
|
},
|
|
{
|
|
"id": 9,
|
|
"loadAddress": "0x400529"
|
|
},
|
|
{
|
|
"id": 10,
|
|
"loadAddress": "0x40052d"
|
|
}
|
|
]''')
|
|
|
|
def testRawDumpInstructions(self):
|
|
self.expect("trace load -v " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"),
|
|
substrs=["intel-pt"])
|
|
|
|
self.expect("thread trace dump instructions --raw --count 21 --forwards",
|
|
substrs=['''thread #1: tid = 3842849
|
|
3: 0x0000000000400511
|
|
7: 0x0000000000400518
|
|
8: 0x000000000040051f
|
|
9: 0x0000000000400529
|
|
10: 0x000000000040052d
|
|
11: 0x0000000000400521
|
|
12: 0x0000000000400525
|
|
13: 0x0000000000400529
|
|
14: 0x000000000040052d
|
|
15: 0x0000000000400521
|
|
16: 0x0000000000400525
|
|
17: 0x0000000000400529
|
|
18: 0x000000000040052d
|
|
19: 0x0000000000400521
|
|
20: 0x0000000000400525
|
|
21: 0x0000000000400529
|
|
22: 0x000000000040052d
|
|
23: 0x0000000000400521
|
|
24: 0x0000000000400525
|
|
25: 0x0000000000400529
|
|
26: 0x000000000040052'''])
|
|
|
|
# We check if we can pass count and skip
|
|
self.expect("thread trace dump instructions --count 5 --skip 6 --raw --forwards",
|
|
substrs=['''thread #1: tid = 3842849
|
|
7: 0x0000000000400518
|
|
8: 0x000000000040051f
|
|
9: 0x0000000000400529
|
|
10: 0x000000000040052d
|
|
11: 0x0000000000400521'''])
|
|
|
|
self.expect("thread trace dump instructions --count 5 --skip 6 --raw",
|
|
substrs=['''thread #1: tid = 3842849
|
|
21: 0x0000000000400529
|
|
20: 0x0000000000400525
|
|
19: 0x0000000000400521
|
|
18: 0x000000000040052d
|
|
17: 0x0000000000400529'''])
|
|
|
|
# We check if we can pass count and skip and instruction id in hex
|
|
self.expect("thread trace dump instructions --count 5 --skip 6 --raw --id 0xE",
|
|
substrs=['''thread #1: tid = 3842849
|
|
8: 0x000000000040051f
|
|
7: 0x0000000000400518
|
|
3: 0x0000000000400511
|
|
no more data'''])
|
|
|
|
# We check if we can pass count and skip and instruction id in decimal
|
|
self.expect("thread trace dump instructions --count 5 --skip 6 --raw --id 14",
|
|
substrs=['''thread #1: tid = 3842849
|
|
8: 0x000000000040051f
|
|
7: 0x0000000000400518
|
|
3: 0x0000000000400511
|
|
no more data'''])
|
|
|
|
# We check if we can access the thread by index id
|
|
self.expect("thread trace dump instructions 1 --raw",
|
|
substrs=['''thread #1: tid = 3842849
|
|
26: 0x000000000040052d'''])
|
|
|
|
# We check that we get an error when using an invalid thread index id
|
|
self.expect("thread trace dump instructions 10", error=True,
|
|
substrs=['error: no thread with index: "10"'])
|
|
|
|
def testDumpFullInstructionsWithMultipleThreads(self):
|
|
# We load a trace with two threads
|
|
self.expect("trace load -v " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "trace_2threads.json"))
|
|
|
|
# We print the instructions of a specific thread
|
|
self.expect("thread trace dump instructions 2 --count 2",
|
|
substrs=['''thread #2: tid = 3842850
|
|
a.out`main + 32 at main.cpp:4
|
|
26: 0x000000000040052d jle 0x400521 ; <+20> at main.cpp:5
|
|
25: 0x0000000000400529 cmpl $0x3, -0x8(%rbp)'''])
|
|
|
|
# We use custom --count and --skip, saving the command to history for later
|
|
self.expect("thread trace dump instructions 2 --count 2 --skip 2", inHistory=True,
|
|
substrs=['''thread #2: tid = 3842850
|
|
a.out`main + 28 at main.cpp:4
|
|
25: 0x0000000000400529 cmpl $0x3, -0x8(%rbp)
|
|
24: 0x0000000000400525 addl $0x1, -0x8(%rbp)'''])
|
|
|
|
# We use a repeat command twice and ensure the previous count is used and the
|
|
# start position moves with each command.
|
|
self.expect("", inHistory=True,
|
|
substrs=['''thread #2: tid = 3842850
|
|
a.out`main + 20 at main.cpp:5
|
|
23: 0x0000000000400521 xorl $0x1, -0x4(%rbp)
|
|
a.out`main + 32 at main.cpp:4
|
|
22: 0x000000000040052d jle 0x400521 ; <+20> at main.cpp:5'''])
|
|
|
|
self.expect("", inHistory=True,
|
|
substrs=['''thread #2: tid = 3842850
|
|
a.out`main + 28 at main.cpp:4
|
|
21: 0x0000000000400529 cmpl $0x3, -0x8(%rbp)
|
|
20: 0x0000000000400525 addl $0x1, -0x8(%rbp'''])
|
|
|
|
def testInvalidBounds(self):
|
|
self.expect("trace load -v " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"))
|
|
|
|
# The output should be work when too many instructions are asked
|
|
self.expect("thread trace dump instructions --count 20 --forwards",
|
|
substrs=['''thread #1: tid = 3842849
|
|
a.out`main + 4 at main.cpp:2
|
|
3: 0x0000000000400511 movl $0x0, -0x4(%rbp)
|
|
a.out`main + 11 at main.cpp:4
|
|
7: 0x0000000000400518 movl $0x0, -0x8(%rbp)
|
|
8: 0x000000000040051f jmp 0x400529 ; <+28> at main.cpp:4'''])
|
|
|
|
# Should print no instructions if the position is out of bounds
|
|
self.expect("thread trace dump instructions --skip 23",
|
|
endstr='no more data\n')
|
|
|
|
# Should fail with negative bounds
|
|
self.expect("thread trace dump instructions --skip -1", error=True)
|
|
self.expect("thread trace dump instructions --count -1", error=True)
|
|
|
|
def testWrongImage(self):
|
|
self.expect("trace load " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "trace_bad_image.json"))
|
|
self.expect("thread trace dump instructions --forwards",
|
|
substrs=['''thread #1: tid = 3842849
|
|
...missing instructions
|
|
3: (error) no memory mapped at this address: 0x0000000000400511'''])
|
|
|
|
def testWrongCPU(self):
|
|
self.expect("trace load " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace", "trace_wrong_cpu.json"))
|
|
self.expect("thread trace dump instructions --forwards",
|
|
substrs=["error: unknown cpu"], error=True)
|
|
|
|
def testMultiFileTraceWithMissingModuleInJSON(self):
|
|
self.expect("trace load " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace-multi-file", "multi-file-no-ld.json"))
|
|
|
|
self.expect("thread trace dump instructions --count 4 --id 9 --forwards --pretty-json",
|
|
substrs=['''[
|
|
{
|
|
"id": 9,
|
|
"loadAddress": "0x40054b",
|
|
"module": "a.out",
|
|
"symbol": "foo()",
|
|
"mnemonic": "jmp"
|
|
},
|
|
{
|
|
"id": 10,
|
|
"loadAddress": "0x400510",
|
|
"module": "a.out",
|
|
"symbol": null,
|
|
"mnemonic": "pushq"
|
|
},
|
|
{
|
|
"id": 11,
|
|
"loadAddress": "0x400516",
|
|
"module": "a.out",
|
|
"symbol": null,
|
|
"mnemonic": "jmpq"
|
|
},
|
|
{
|
|
"id": 12,
|
|
"error": "no memory mapped at this address: 0x00007ffff7df1950"
|
|
},
|
|
{
|
|
"id": 16,
|
|
"loadAddress": "0x400674",
|
|
"module": "a.out",
|
|
"symbol": "main",
|
|
"mnemonic": "movl",
|
|
"source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp",
|
|
"line": 10,
|
|
"column": 0
|
|
}
|
|
]'''])
|
|
|
|
self.expect("thread trace dump instructions --count 4 --id 20 --forwards --pretty-json",
|
|
substrs=['''[
|
|
{
|
|
"id": 20,
|
|
"loadAddress": "0x400677",
|
|
"module": "a.out",
|
|
"symbol": "main",
|
|
"mnemonic": "movl",
|
|
"source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp",
|
|
"line": 12,
|
|
"column": 0
|
|
},
|
|
{
|
|
"id": 21,
|
|
"loadAddress": "0x40067a",
|
|
"module": "a.out",
|
|
"symbol": "main",
|
|
"mnemonic": "addl",
|
|
"source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp",
|
|
"line": 12,
|
|
"column": 0
|
|
},
|
|
{
|
|
"id": 22,
|
|
"loadAddress": "0x40067f",
|
|
"module": "a.out",
|
|
"symbol": "main",
|
|
"mnemonic": "movl",
|
|
"source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp",
|
|
"line": 12,
|
|
"column": 0
|
|
},
|
|
{
|
|
"id": 26,
|
|
"loadAddress": "0x400682",
|
|
"module": "a.out",
|
|
"symbol": "inline_function()",
|
|
"mnemonic": "movl",
|
|
"source": "/home/wallace/llvm-sand/external/llvm-project/lldb/test/API/commands/trace/intelpt-trace-multi-file/main.cpp",
|
|
"line": 4,
|
|
"column": 0
|
|
}
|
|
]'''])
|
|
|
|
def testMultiFileTraceWithMissingModule(self):
|
|
self.expect("trace load " +
|
|
os.path.join(self.getSourceDir(), "intelpt-trace-multi-file", "multi-file-no-ld.json"))
|
|
|
|
# This instructions in this test covers the following flow:
|
|
#
|
|
# - The trace starts with a call to libfoo, which triggers the dynamic
|
|
# linker, but the dynamic linker is not included in the JSON file,
|
|
# thus the trace reports a set of missing instructions after
|
|
# instruction [6].
|
|
# - Then, the dump continues in the next synchronization point showing
|
|
# a call to an inlined function, which is displayed as [inlined].
|
|
# - Finally, a call to libfoo is performed, which invokes libbar inside.
|
|
#
|
|
# Whenever there's a line or symbol change, including the inline case, a
|
|
# line is printed showing the symbol context change.
|
|
#
|
|
# Finally, the instruction disassembly is included in the dump.
|
|
self.expect("thread trace dump instructions --count 50 --forwards",
|
|
substrs=['''thread #1: tid = 815455
|
|
a.out`main + 15 at main.cpp:10
|
|
3: 0x000000000040066f callq 0x400540 ; symbol stub for: foo()
|
|
a.out`symbol stub for: foo()
|
|
7: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40
|
|
8: 0x0000000000400546 pushq $0x2
|
|
9: 0x000000000040054b jmp 0x400510
|
|
a.out`(none)
|
|
10: 0x0000000000400510 pushq 0x200af2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 8
|
|
11: 0x0000000000400516 jmpq *0x200af4(%rip) ; _GLOBAL_OFFSET_TABLE_ + 16
|
|
...missing instructions
|
|
12: (error) no memory mapped at this address: 0x00007ffff7df1950
|
|
a.out`main + 20 at main.cpp:10
|
|
16: 0x0000000000400674 movl %eax, -0xc(%rbp)
|
|
a.out`main + 23 at main.cpp:12
|
|
20: 0x0000000000400677 movl -0xc(%rbp), %eax
|
|
21: 0x000000000040067a addl $0x1, %eax
|
|
22: 0x000000000040067f movl %eax, -0xc(%rbp)
|
|
a.out`main + 34 [inlined] inline_function() at main.cpp:4
|
|
26: 0x0000000000400682 movl $0x0, -0x4(%rbp)
|
|
a.out`main + 41 [inlined] inline_function() + 7 at main.cpp:5
|
|
27: 0x0000000000400689 movl -0x4(%rbp), %eax
|
|
28: 0x000000000040068c addl $0x1, %eax
|
|
29: 0x0000000000400691 movl %eax, -0x4(%rbp)
|
|
a.out`main + 52 [inlined] inline_function() + 18 at main.cpp:6
|
|
30: 0x0000000000400694 movl -0x4(%rbp), %eax
|
|
a.out`main + 55 at main.cpp:14
|
|
31: 0x0000000000400697 movl -0xc(%rbp), %ecx
|
|
32: 0x000000000040069a addl %eax, %ecx
|
|
33: 0x000000000040069c movl %ecx, -0xc(%rbp)
|
|
a.out`main + 63 at main.cpp:16
|
|
37: 0x000000000040069f callq 0x400540 ; symbol stub for: foo()
|
|
a.out`symbol stub for: foo()
|
|
38: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40
|
|
libfoo.so`foo() at foo.cpp:3
|
|
39: 0x00007ffff7bd96e0 pushq %rbp
|
|
40: 0x00007ffff7bd96e1 movq %rsp, %rbp
|
|
libfoo.so`foo() + 4 at foo.cpp:4
|
|
41: 0x00007ffff7bd96e4 subq $0x10, %rsp
|
|
42: 0x00007ffff7bd96e8 callq 0x7ffff7bd95d0 ; symbol stub for: bar()
|
|
libfoo.so`symbol stub for: bar()
|
|
43: 0x00007ffff7bd95d0 jmpq *0x200a4a(%rip) ; _GLOBAL_OFFSET_TABLE_ + 32
|
|
libbar.so`bar() at bar.cpp:1
|
|
44: 0x00007ffff79d7690 pushq %rbp
|
|
45: 0x00007ffff79d7691 movq %rsp, %rbp
|
|
libbar.so`bar() + 4 at bar.cpp:2
|
|
46: 0x00007ffff79d7694 movl $0x1, -0x4(%rbp)
|
|
libbar.so`bar() + 11 at bar.cpp:3
|
|
47: 0x00007ffff79d769b movl -0x4(%rbp), %eax
|
|
48: 0x00007ffff79d769e addl $0x1, %eax
|
|
49: 0x00007ffff79d76a3 movl %eax, -0x4(%rbp)
|
|
libbar.so`bar() + 22 at bar.cpp:4
|
|
50: 0x00007ffff79d76a6 movl -0x4(%rbp), %eax
|
|
51: 0x00007ffff79d76a9 popq %rbp
|
|
52: 0x00007ffff79d76aa retq''',
|
|
'''libfoo.so`foo() + 13 at foo.cpp:4
|
|
53: 0x00007ffff7bd96ed movl %eax, -0x4(%rbp)
|
|
libfoo.so`foo() + 16 at foo.cpp:5
|
|
54: 0x00007ffff7bd96f0 movl -0x4(%rbp), %eax
|
|
55: 0x00007ffff7bd96f3 addl $0x1, %eax
|
|
56: 0x00007ffff7bd96f8 movl %eax, -0x4(%rbp)
|
|
libfoo.so`foo() + 27 at foo.cpp:6
|
|
57: 0x00007ffff7bd96fb movl -0x4(%rbp), %eax
|
|
58: 0x00007ffff7bd96fe addq $0x10, %rsp
|
|
59: 0x00007ffff7bd9702 popq %rbp
|
|
60: 0x00007ffff7bd9703 retq''',
|
|
'''a.out`main + 68 at main.cpp:16
|
|
61: 0x00000000004006a4 movl -0xc(%rbp), %ecx
|
|
62: 0x00000000004006a7 addl %eax, %ecx
|
|
63: 0x00000000004006a9 movl %ecx, -0xc(%rbp)
|
|
no more data'''])
|
|
|
|
|
|
self.expect("thread trace dump instructions --count 50",
|
|
substrs=['''thread #1: tid = 815455
|
|
a.out`main + 73 at main.cpp:16
|
|
63: 0x00000000004006a9 movl %ecx, -0xc(%rbp)
|
|
62: 0x00000000004006a7 addl %eax, %ecx
|
|
61: 0x00000000004006a4 movl -0xc(%rbp), %ecx
|
|
libfoo.so`foo() + 35 at foo.cpp:6
|
|
60: 0x00007ffff7bd9703 retq''',
|
|
'''59: 0x00007ffff7bd9702 popq %rbp
|
|
58: 0x00007ffff7bd96fe addq $0x10, %rsp
|
|
57: 0x00007ffff7bd96fb movl -0x4(%rbp), %eax
|
|
libfoo.so`foo() + 24 at foo.cpp:5
|
|
56: 0x00007ffff7bd96f8 movl %eax, -0x4(%rbp)
|
|
55: 0x00007ffff7bd96f3 addl $0x1, %eax
|
|
54: 0x00007ffff7bd96f0 movl -0x4(%rbp), %eax
|
|
libfoo.so`foo() + 13 at foo.cpp:4
|
|
53: 0x00007ffff7bd96ed movl %eax, -0x4(%rbp)
|
|
libbar.so`bar() + 26 at bar.cpp:4
|
|
52: 0x00007ffff79d76aa retq''',
|
|
'''51: 0x00007ffff79d76a9 popq %rbp
|
|
50: 0x00007ffff79d76a6 movl -0x4(%rbp), %eax
|
|
libbar.so`bar() + 19 at bar.cpp:3
|
|
49: 0x00007ffff79d76a3 movl %eax, -0x4(%rbp)
|
|
48: 0x00007ffff79d769e addl $0x1, %eax
|
|
47: 0x00007ffff79d769b movl -0x4(%rbp), %eax
|
|
libbar.so`bar() + 4 at bar.cpp:2
|
|
46: 0x00007ffff79d7694 movl $0x1, -0x4(%rbp)
|
|
libbar.so`bar() + 1 at bar.cpp:1
|
|
45: 0x00007ffff79d7691 movq %rsp, %rbp
|
|
44: 0x00007ffff79d7690 pushq %rbp
|
|
libfoo.so`symbol stub for: bar()
|
|
43: 0x00007ffff7bd95d0 jmpq *0x200a4a(%rip) ; _GLOBAL_OFFSET_TABLE_ + 32
|
|
libfoo.so`foo() + 8 at foo.cpp:4
|
|
42: 0x00007ffff7bd96e8 callq 0x7ffff7bd95d0 ; symbol stub for: bar()
|
|
41: 0x00007ffff7bd96e4 subq $0x10, %rsp
|
|
libfoo.so`foo() + 1 at foo.cpp:3
|
|
40: 0x00007ffff7bd96e1 movq %rsp, %rbp
|
|
39: 0x00007ffff7bd96e0 pushq %rbp
|
|
a.out`symbol stub for: foo()
|
|
38: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40
|
|
a.out`main + 63 at main.cpp:16
|
|
37: 0x000000000040069f callq 0x400540 ; symbol stub for: foo()
|
|
a.out`main + 60 at main.cpp:14
|
|
33: 0x000000000040069c movl %ecx, -0xc(%rbp)
|
|
32: 0x000000000040069a addl %eax, %ecx
|
|
31: 0x0000000000400697 movl -0xc(%rbp), %ecx
|
|
a.out`main + 52 [inlined] inline_function() + 18 at main.cpp:6
|
|
30: 0x0000000000400694 movl -0x4(%rbp), %eax
|
|
a.out`main + 49 [inlined] inline_function() + 15 at main.cpp:5
|
|
29: 0x0000000000400691 movl %eax, -0x4(%rbp)
|
|
28: 0x000000000040068c addl $0x1, %eax
|
|
27: 0x0000000000400689 movl -0x4(%rbp), %eax
|
|
a.out`main + 34 [inlined] inline_function() at main.cpp:4
|
|
26: 0x0000000000400682 movl $0x0, -0x4(%rbp)
|
|
a.out`main + 31 at main.cpp:12
|
|
22: 0x000000000040067f movl %eax, -0xc(%rbp)
|
|
21: 0x000000000040067a addl $0x1, %eax
|
|
20: 0x0000000000400677 movl -0xc(%rbp), %eax
|
|
a.out`main + 20 at main.cpp:10
|
|
16: 0x0000000000400674 movl %eax, -0xc(%rbp)
|
|
...missing instructions
|
|
12: (error) no memory mapped at this address: 0x00007ffff7df1950
|
|
a.out`(none)
|
|
11: 0x0000000000400516 jmpq *0x200af4(%rip) ; _GLOBAL_OFFSET_TABLE_ + 16
|
|
10: 0x0000000000400510 pushq 0x200af2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 8
|
|
a.out`symbol stub for: foo() + 11
|
|
9: 0x000000000040054b jmp 0x400510
|
|
8: 0x0000000000400546 pushq $0x2
|
|
7: 0x0000000000400540 jmpq *0x200ae2(%rip) ; _GLOBAL_OFFSET_TABLE_ + 40
|
|
a.out`main + 15 at main.cpp:10
|
|
3: 0x000000000040066f callq 0x400540 ; symbol stub for: foo()
|
|
no more data'''])
|
|
|
|
self.expect("thread trace dump instructions --skip 100 --forwards", inHistory=True,
|
|
substrs=['''thread #1: tid = 815455
|
|
no more data'''])
|
|
|
|
self.expect("", substrs=['''thread #1: tid = 815455
|
|
no more data'''])
|
|
|
|
|
|
self.expect("thread trace dump instructions --raw --all --forwards",
|
|
substrs=['''thread #1: tid = 815455
|
|
3: 0x000000000040066f
|
|
7: 0x0000000000400540''',
|
|
'''11: 0x0000000000400516
|
|
...missing instructions
|
|
12: (error) no memory mapped at this address: 0x00007ffff7df1950
|
|
16: 0x0000000000400674''',
|
|
'''61: 0x00000000004006a4
|
|
62: 0x00000000004006a7
|
|
63: 0x00000000004006a9
|
|
no more data'''])
|