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