1import lldb
2from lldbsuite.test.lldbtest import *
3from lldbsuite.test import lldbutil
4from lldbsuite.test.decorators import *
5
6ADDRESS_REGEX = '0x[0-9a-fA-F]*'
7
8class TestTraceStartStopMultipleThreads(TestBase):
9
10    mydir = TestBase.compute_mydir(__file__)
11    NO_DEBUG_INFO_TESTCASE = True
12
13    def setUp(self):
14        TestBase.setUp(self)
15        if 'intel-pt' not in configuration.enabled_plugins:
16            self.skipTest("The intel-pt test plugin is not enabled")
17
18    @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
19    def testStartMultipleLiveThreads(self):
20        self.build()
21        exe = self.getBuildArtifact("a.out")
22        target = self.dbg.CreateTarget(exe)
23
24        self.expect("b main")
25        self.expect("b 6")
26        self.expect("b 11")
27
28        self.expect("r")
29        self.expect("proce trace start")
30
31
32        # We'll see here the first thread
33        self.expect("continue")
34        self.expect("thread trace dump instructions", substrs=['main.cpp:9'])
35
36        # We'll see here the second thread
37        self.expect("continue")
38        self.expect("thread trace dump instructions", substrs=['main.cpp:4'])
39
40    @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
41    def testStartMultipleLiveThreadsWithStops(self):
42        self.build()
43        exe = self.getBuildArtifact("a.out")
44        target = self.dbg.CreateTarget(exe)
45
46        self.expect("b main")
47        self.expect("b 6")
48        self.expect("b 11")
49
50        self.expect("r")
51        self.expect("process trace start")
52
53
54        # We'll see here the first thread
55        self.expect("continue")
56
57        # We are in thread 2
58        self.expect("thread trace dump instructions", substrs=['main.cpp:9'])
59        self.expect("thread trace dump instructions 2", substrs=['main.cpp:9'])
60
61        # We stop tracing it
62        self.expect("thread trace stop 2")
63
64        # The trace is still in memory
65        self.expect("thread trace dump instructions 2", substrs=['main.cpp:9'])
66
67        # We'll stop at the next breakpoint, thread 2 will be still alive, but not traced. Thread 3 will be traced
68        self.expect("continue")
69        self.expect("thread trace dump instructions", substrs=['main.cpp:4'])
70        self.expect("thread trace dump instructions 3", substrs=['main.cpp:4'])
71
72        self.expect("thread trace dump instructions 2", substrs=['not traced'])
73
74    @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
75    def testStartMultipleLiveThreadsWithStops(self):
76        self.build()
77        exe = self.getBuildArtifact("a.out")
78        target = self.dbg.CreateTarget(exe)
79
80        self.expect("b main")
81        self.expect("b 6")
82        self.expect("b 11")
83
84        self.expect("r")
85        self.expect("process trace start")
86
87        # We'll see here the first thread
88        self.expect("continue")
89
90        # We are in thread 2
91        self.expect("thread trace dump instructions", substrs=['main.cpp:9'])
92        self.expect("thread trace dump instructions 2", substrs=['main.cpp:9'])
93
94        # We stop tracing all
95        self.expect("thread trace stop all")
96
97        # The trace is still in memory
98        self.expect("thread trace dump instructions 2", substrs=['main.cpp:9'])
99
100        # We'll stop at the next breakpoint in thread 3, thread 2 and 3 will be alive, but only 3 traced.
101        self.expect("continue")
102        self.expect("thread trace dump instructions", substrs=['main.cpp:4'])
103        self.expect("thread trace dump instructions 3", substrs=['main.cpp:4'])
104        self.expect("thread trace dump instructions 1", substrs=['not traced'])
105        self.expect("thread trace dump instructions 2", substrs=['not traced'])
106
107    @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
108    def testStartMultipleLiveThreadsWithThreadStartAll(self):
109        self.build()
110        exe = self.getBuildArtifact("a.out")
111        target = self.dbg.CreateTarget(exe)
112
113        self.expect("b main")
114        self.expect("b 6")
115        self.expect("b 11")
116
117        self.expect("r")
118
119        self.expect("continue")
120        # We are in thread 2
121        self.expect("thread trace start all")
122        # Now we have instructions in thread's 2 trace
123        self.expect("n")
124
125        self.expect("thread trace dump instructions 2", substrs=['main.cpp:11'])
126
127        # We stop tracing all
128        self.runCmd("thread trace stop all")
129
130        # The trace is still in memory
131        self.expect("thread trace dump instructions 2", substrs=['main.cpp:11'])
132
133        # We'll stop at the next breakpoint in thread 3, and nothing should be traced
134        self.expect("continue")
135        self.expect("thread trace dump instructions 3", substrs=['not traced'])
136        self.expect("thread trace dump instructions 1", substrs=['not traced'])
137        self.expect("thread trace dump instructions 2", substrs=['not traced'])
138
139    @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
140    def testStartMultipleLiveThreadsWithSmallTotalLimit(self):
141        self.build()
142        exe = self.getBuildArtifact("a.out")
143        target = self.dbg.CreateTarget(exe)
144
145        self.expect("b main")
146        self.expect("r")
147        # trace the entire process with enough total size for 1 thread trace
148        self.expect("process trace start -l 5000")
149        # we get the stop event when trace 2 appears and can't be traced
150        self.expect("c", substrs=['Thread', "can't be traced"])
151        # we get the stop event when trace 3 appears and can't be traced
152        self.expect("c", substrs=['Thread', "can't be traced"])
153