1import lldb
2from intelpt_testcase import *
3from lldbsuite.test.lldbtest import *
4from lldbsuite.test import lldbutil
5from lldbsuite.test.decorators import *
6
7class TestTraceEvents(TraceIntelPTTestCaseBase):
8
9    mydir = TestBase.compute_mydir(__file__)
10
11    @testSBAPIAndCommands
12    def testPauseEvents(self):
13      '''
14        Everytime the target stops running on the CPU, a 'disabled' event will
15        be emitted, which is represented by the TraceCursor API as a 'paused'
16        event.
17      '''
18      self.expect("target create " +
19            os.path.join(self.getSourceDir(), "intelpt-trace-multi-file", "a.out"))
20      self.expect("b 12")
21      self.expect("r")
22      self.traceStartThread()
23      self.expect("n")
24      self.expect("n")
25      self.expect("si")
26      self.expect("si")
27      self.expect("si")
28      # We ensure that the paused events are printed correctly forward
29      self.expect("thread trace dump instructions -e -f",
30        patterns=[f'''thread #1: tid = .*
31  a.out`main \+ 23 at main.cpp:12
32    0: {ADDRESS_REGEX}    movl .*
33  \[paused\]
34    1: {ADDRESS_REGEX}    addl .*
35    2: {ADDRESS_REGEX}    movl .*
36  \[paused\]
37  a.out`main \+ 34 \[inlined\] inline_function\(\) at main.cpp:4
38    3: {ADDRESS_REGEX}    movl .*
39  a.out`main \+ 41 \[inlined\] inline_function\(\) \+ 7 at main.cpp:5
40    4: {ADDRESS_REGEX}    movl .*
41    5: {ADDRESS_REGEX}    addl .*
42    6: {ADDRESS_REGEX}    movl .*
43  a.out`main \+ 52 \[inlined\] inline_function\(\) \+ 18 at main.cpp:6
44    7: {ADDRESS_REGEX}    movl .*
45  a.out`main \+ 55 at main.cpp:14
46    8: {ADDRESS_REGEX}    movl .*
47    9: {ADDRESS_REGEX}    addl .*
48    10: {ADDRESS_REGEX}    movl .*
49  \[paused\]
50  a.out`main \+ 63 at main.cpp:16
51    11: {ADDRESS_REGEX}    callq  .* ; symbol stub for: foo\(\)
52  \[paused\]
53  a.out`symbol stub for: foo\(\)
54    12: {ADDRESS_REGEX}    jmpq'''])
55
56      # We ensure that the paused events are printed correctly backward
57      self.expect("thread trace dump instructions -e --id 12",
58        patterns=[f'''thread #1: tid = .*
59  a.out`symbol stub for: foo\(\)
60    12: {ADDRESS_REGEX}    jmpq .*
61  \[paused\]
62  a.out`main \+ 63 at main.cpp:16
63    11: {ADDRESS_REGEX}    callq  .* ; symbol stub for: foo\(\)
64  \[paused\]
65  a.out`main \+ 60 at main.cpp:14
66    10: {ADDRESS_REGEX}    movl .*
67    9: {ADDRESS_REGEX}    addl .*
68    8: {ADDRESS_REGEX}    movl .*
69  a.out`main \+ 52 \[inlined\] inline_function\(\) \+ 18 at main.cpp:6
70    7: {ADDRESS_REGEX}    movl .*
71  a.out`main \+ 49 \[inlined\] inline_function\(\) \+ 15 at main.cpp:5
72    6: {ADDRESS_REGEX}    movl .*
73    5: {ADDRESS_REGEX}    addl .*
74    4: {ADDRESS_REGEX}    movl .*
75  a.out`main \+ 34 \[inlined\] inline_function\(\) at main.cpp:4
76    3: {ADDRESS_REGEX}    movl .*
77  \[paused\]
78  a.out`main \+ 31 at main.cpp:12
79    2: {ADDRESS_REGEX}    movl .*
80    1: {ADDRESS_REGEX}    addl .*
81  \[paused\]
82    0: {ADDRESS_REGEX}    movl .*'''])
83