xref: /llvm-project/lldb/test/API/commands/trace/TestTraceStartStop.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1fb19f11eSWalter Erquinigoimport lldb
2bf9f21a2SWalter Erquinigofrom intelpt_testcase import *
3fb19f11eSWalter Erquinigofrom lldbsuite.test.lldbtest import *
4fb19f11eSWalter Erquinigofrom lldbsuite.test import lldbutil
5fb19f11eSWalter Erquinigofrom lldbsuite.test.decorators import *
6fb19f11eSWalter Erquinigo
7fb19f11eSWalter Erquinigo
8*2238dcc3SJonas Devlieghereclass TestTraceStartStop(TraceIntelPTTestCaseBase):
9fb19f11eSWalter Erquinigo    def expectGenericHelpMessageForStartCommand(self):
10*2238dcc3SJonas Devlieghere        self.expect(
11*2238dcc3SJonas Devlieghere            "help thread trace start",
12*2238dcc3SJonas Devlieghere            substrs=["Syntax: thread trace start [<trace-options>]"],
13*2238dcc3SJonas Devlieghere        )
14fb19f11eSWalter Erquinigo
15bf9f21a2SWalter Erquinigo    @testSBAPIAndCommands
16fb19f11eSWalter Erquinigo    def testStartStopSessionFileThreads(self):
17fb19f11eSWalter Erquinigo        # it should fail for processes from json session files
18*2238dcc3SJonas Devlieghere        self.expect(
19*2238dcc3SJonas Devlieghere            "trace load -v "
20*2238dcc3SJonas Devlieghere            + os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json")
21*2238dcc3SJonas Devlieghere        )
22fb19f11eSWalter Erquinigo
23fb19f11eSWalter Erquinigo        # the help command should be the generic one, as it's not a live process
24fb19f11eSWalter Erquinigo        self.expectGenericHelpMessageForStartCommand()
25fb19f11eSWalter Erquinigo
26bf9f21a2SWalter Erquinigo        self.traceStartThread(error=True)
270b697561SWalter Erquinigo
28bf9f21a2SWalter Erquinigo        self.traceStopThread(error=True)
29bf9f21a2SWalter Erquinigo
30bf9f21a2SWalter Erquinigo    @testSBAPIAndCommands
310b697561SWalter Erquinigo    def testStartWithNoProcess(self):
32bf9f21a2SWalter Erquinigo        self.traceStartThread(error=True)
330b697561SWalter Erquinigo
34bf9f21a2SWalter Erquinigo    @testSBAPIAndCommands
350b697561SWalter Erquinigo    def testStartSessionWithWrongSize(self):
36*2238dcc3SJonas Devlieghere        self.expect(
37*2238dcc3SJonas Devlieghere            "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")
38*2238dcc3SJonas Devlieghere        )
390b697561SWalter Erquinigo        self.expect("b main")
400b697561SWalter Erquinigo        self.expect("r")
41bf9f21a2SWalter Erquinigo
42bf9f21a2SWalter Erquinigo        self.traceStartThread(
43*2238dcc3SJonas Devlieghere            error=True,
44*2238dcc3SJonas Devlieghere            iptTraceSize=2000,
45*2238dcc3SJonas Devlieghere            substrs=["The intel pt trace size must be a power of 2", "It was 2000"],
46*2238dcc3SJonas Devlieghere        )
47bf9f21a2SWalter Erquinigo
48bf9f21a2SWalter Erquinigo        self.traceStartThread(
49*2238dcc3SJonas Devlieghere            error=True,
50*2238dcc3SJonas Devlieghere            iptTraceSize=5000,
51*2238dcc3SJonas Devlieghere            substrs=["The intel pt trace size must be a power of 2", "It was 5000"],
52*2238dcc3SJonas Devlieghere        )
53bf9f21a2SWalter Erquinigo
54bf9f21a2SWalter Erquinigo        self.traceStartThread(
55*2238dcc3SJonas Devlieghere            error=True,
56*2238dcc3SJonas Devlieghere            iptTraceSize=0,
57*2238dcc3SJonas Devlieghere            substrs=["The intel pt trace size must be a power of 2", "It was 0"],
58*2238dcc3SJonas Devlieghere        )
59bf9f21a2SWalter Erquinigo
606a5355e8SWalter Erquinigo        self.traceStartThread(iptTraceSize=1048576)
61bf9f21a2SWalter Erquinigo
62db73a52dSrnofenko    @testSBAPIAndCommands
63db73a52dSrnofenko    def testStartSessionWithSizeDeclarationInUnits(self):
64*2238dcc3SJonas Devlieghere        self.expect(
65*2238dcc3SJonas Devlieghere            "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")
66*2238dcc3SJonas Devlieghere        )
67db73a52dSrnofenko        self.expect("b main")
68db73a52dSrnofenko        self.expect("r")
69db73a52dSrnofenko
70db73a52dSrnofenko        self.traceStartThread(
71*2238dcc3SJonas Devlieghere            error=True,
72*2238dcc3SJonas Devlieghere            iptTraceSize="abc",
73*2238dcc3SJonas Devlieghere            substrs=["invalid bytes expression for 'abc'"],
74*2238dcc3SJonas Devlieghere        )
75db73a52dSrnofenko
76db73a52dSrnofenko        self.traceStartThread(
77*2238dcc3SJonas Devlieghere            error=True,
78*2238dcc3SJonas Devlieghere            iptTraceSize="123.12",
79*2238dcc3SJonas Devlieghere            substrs=["invalid bytes expression for '123.12'"],
80*2238dcc3SJonas Devlieghere        )
81db73a52dSrnofenko
82db73a52dSrnofenko        self.traceStartThread(
83*2238dcc3SJonas Devlieghere            error=True, iptTraceSize='""', substrs=["invalid bytes expression for ''"]
84*2238dcc3SJonas Devlieghere        )
85db73a52dSrnofenko
86db73a52dSrnofenko        self.traceStartThread(
87*2238dcc3SJonas Devlieghere            error=True,
88*2238dcc3SJonas Devlieghere            iptTraceSize="2000B",
89*2238dcc3SJonas Devlieghere            substrs=[
90*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 2000"
91*2238dcc3SJonas Devlieghere            ],
92*2238dcc3SJonas Devlieghere        )
93db73a52dSrnofenko
94db73a52dSrnofenko        self.traceStartThread(
95*2238dcc3SJonas Devlieghere            error=True,
96*2238dcc3SJonas Devlieghere            iptTraceSize="3MB",
97*2238dcc3SJonas Devlieghere            substrs=[
98*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 3145728"
99*2238dcc3SJonas Devlieghere            ],
100*2238dcc3SJonas Devlieghere        )
101db73a52dSrnofenko
102db73a52dSrnofenko        self.traceStartThread(
103*2238dcc3SJonas Devlieghere            error=True,
104*2238dcc3SJonas Devlieghere            iptTraceSize="3MiB",
105*2238dcc3SJonas Devlieghere            substrs=[
106*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 3145728"
107*2238dcc3SJonas Devlieghere            ],
108*2238dcc3SJonas Devlieghere        )
109db73a52dSrnofenko
110db73a52dSrnofenko        self.traceStartThread(
111*2238dcc3SJonas Devlieghere            error=True,
112*2238dcc3SJonas Devlieghere            iptTraceSize="3mib",
113*2238dcc3SJonas Devlieghere            substrs=[
114*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 3145728"
115*2238dcc3SJonas Devlieghere            ],
116*2238dcc3SJonas Devlieghere        )
117db73a52dSrnofenko
118db73a52dSrnofenko        self.traceStartThread(
119*2238dcc3SJonas Devlieghere            error=True,
120*2238dcc3SJonas Devlieghere            iptTraceSize="3M",
121*2238dcc3SJonas Devlieghere            substrs=[
122*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 3145728"
123*2238dcc3SJonas Devlieghere            ],
124*2238dcc3SJonas Devlieghere        )
125db73a52dSrnofenko
126db73a52dSrnofenko        self.traceStartThread(
127*2238dcc3SJonas Devlieghere            error=True,
128*2238dcc3SJonas Devlieghere            iptTraceSize="3KB",
129*2238dcc3SJonas Devlieghere            substrs=[
130*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 3072"
131*2238dcc3SJonas Devlieghere            ],
132*2238dcc3SJonas Devlieghere        )
133db73a52dSrnofenko
134db73a52dSrnofenko        self.traceStartThread(
135*2238dcc3SJonas Devlieghere            error=True,
136*2238dcc3SJonas Devlieghere            iptTraceSize="3KiB",
137*2238dcc3SJonas Devlieghere            substrs=[
138*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 3072"
139*2238dcc3SJonas Devlieghere            ],
140*2238dcc3SJonas Devlieghere        )
141db73a52dSrnofenko
142db73a52dSrnofenko        self.traceStartThread(
143*2238dcc3SJonas Devlieghere            error=True,
144*2238dcc3SJonas Devlieghere            iptTraceSize="3K",
145*2238dcc3SJonas Devlieghere            substrs=[
146*2238dcc3SJonas Devlieghere                "The intel pt trace size must be a power of 2 greater than or equal to 4096 (2^12) bytes. It was 3072"
147*2238dcc3SJonas Devlieghere            ],
148*2238dcc3SJonas Devlieghere        )
149db73a52dSrnofenko
150db73a52dSrnofenko        self.traceStartThread(
151*2238dcc3SJonas Devlieghere            error=True,
152*2238dcc3SJonas Devlieghere            iptTraceSize="3MS",
153*2238dcc3SJonas Devlieghere            substrs=["invalid bytes expression for '3MS'"],
154*2238dcc3SJonas Devlieghere        )
155db73a52dSrnofenko
156db73a52dSrnofenko        self.traceStartThread(iptTraceSize="1048576")
157db73a52dSrnofenko
158*2238dcc3SJonas Devlieghere    @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
159bf9f21a2SWalter Erquinigo    def testSBAPIHelp(self):
160*2238dcc3SJonas Devlieghere        self.expect(
161*2238dcc3SJonas Devlieghere            "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")
162*2238dcc3SJonas Devlieghere        )
163bf9f21a2SWalter Erquinigo        self.expect("b main")
164bf9f21a2SWalter Erquinigo        self.expect("r")
165bf9f21a2SWalter Erquinigo
166bf9f21a2SWalter Erquinigo        help = self.getTraceOrCreate().GetStartConfigurationHelp()
1676a5355e8SWalter Erquinigo        self.assertIn("iptTraceSize", help)
168bf9f21a2SWalter Erquinigo        self.assertIn("processBufferSizeLimit", help)
169bf9f21a2SWalter Erquinigo
170*2238dcc3SJonas Devlieghere    @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
171bf9f21a2SWalter Erquinigo    def testStoppingAThread(self):
172*2238dcc3SJonas Devlieghere        self.expect(
173*2238dcc3SJonas Devlieghere            "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")
174*2238dcc3SJonas Devlieghere        )
175bf9f21a2SWalter Erquinigo        self.expect("b main")
176bf9f21a2SWalter Erquinigo        self.expect("r")
177bf9f21a2SWalter Erquinigo        self.expect("thread trace start")
178bf9f21a2SWalter Erquinigo        self.expect("n")
179*2238dcc3SJonas Devlieghere        self.expect(
180*2238dcc3SJonas Devlieghere            "thread trace dump instructions",
181*2238dcc3SJonas Devlieghere            substrs=[
182*2238dcc3SJonas Devlieghere                """0x0000000000400511    movl   $0x0, -0x4(%rbp)
183*2238dcc3SJonas Devlieghere    no more data"""
184*2238dcc3SJonas Devlieghere            ],
185*2238dcc3SJonas Devlieghere        )
186bf9f21a2SWalter Erquinigo        # process stopping should stop the thread
187bf9f21a2SWalter Erquinigo        self.expect("process trace stop")
188bf9f21a2SWalter Erquinigo        self.expect("n")
189*2238dcc3SJonas Devlieghere        self.expect(
190*2238dcc3SJonas Devlieghere            "thread trace dump instructions", substrs=["not traced"], error=True
191*2238dcc3SJonas Devlieghere        )
1920b697561SWalter Erquinigo
193*2238dcc3SJonas Devlieghere    @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))
194fb19f11eSWalter Erquinigo    def testStartStopLiveThreads(self):
195fb19f11eSWalter Erquinigo        # The help command should be the generic one if there's no process running
196fb19f11eSWalter Erquinigo        self.expectGenericHelpMessageForStartCommand()
197fb19f11eSWalter Erquinigo
198*2238dcc3SJonas Devlieghere        self.expect(
199*2238dcc3SJonas Devlieghere            "thread trace start", error=True, substrs=["error: Process not available"]
200*2238dcc3SJonas Devlieghere        )
201fb19f11eSWalter Erquinigo
202*2238dcc3SJonas Devlieghere        self.expect(
203*2238dcc3SJonas Devlieghere            "file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out")
204*2238dcc3SJonas Devlieghere        )
205fb19f11eSWalter Erquinigo        self.expect("b main")
206fb19f11eSWalter Erquinigo
207*2238dcc3SJonas Devlieghere        self.expect(
208*2238dcc3SJonas Devlieghere            "thread trace start", error=True, substrs=["error: Process not available"]
209*2238dcc3SJonas Devlieghere        )
210fb19f11eSWalter Erquinigo
211fb19f11eSWalter Erquinigo        # The help command should be the generic one if there's still no process running
212fb19f11eSWalter Erquinigo        self.expectGenericHelpMessageForStartCommand()
213fb19f11eSWalter Erquinigo
214fb19f11eSWalter Erquinigo        self.expect("r")
215fb19f11eSWalter Erquinigo
2160b697561SWalter Erquinigo        # This fails because "trace start" hasn't been called yet
217*2238dcc3SJonas Devlieghere        self.expect(
218*2238dcc3SJonas Devlieghere            "thread trace stop",
219*2238dcc3SJonas Devlieghere            error=True,
220*2238dcc3SJonas Devlieghere            substrs=["error: Process is not being traced"],
221*2238dcc3SJonas Devlieghere        )
2220b697561SWalter Erquinigo
223fb19f11eSWalter Erquinigo        # the help command should be the intel-pt one now
224*2238dcc3SJonas Devlieghere        self.expect(
225*2238dcc3SJonas Devlieghere            "help thread trace start",
226*2238dcc3SJonas Devlieghere            substrs=[
227*2238dcc3SJonas Devlieghere                "Start tracing one or more threads with intel-pt.",
228*2238dcc3SJonas Devlieghere                "Syntax: thread trace start [<thread-index> <thread-index> ...] [<intel-pt-options>]",
229*2238dcc3SJonas Devlieghere            ],
230*2238dcc3SJonas Devlieghere        )
231fb19f11eSWalter Erquinigo
2320b697561SWalter Erquinigo        # We start tracing with a small buffer size
2330b697561SWalter Erquinigo        self.expect("thread trace start 1 --size 4096")
234fb19f11eSWalter Erquinigo
2350b697561SWalter Erquinigo        # We fail if we try to trace again
236*2238dcc3SJonas Devlieghere        self.expect(
237*2238dcc3SJonas Devlieghere            "thread trace start",
238*2238dcc3SJonas Devlieghere            error=True,
239*2238dcc3SJonas Devlieghere            substrs=["error: Thread ", "already traced"],
240*2238dcc3SJonas Devlieghere        )
241fb19f11eSWalter Erquinigo
2420b697561SWalter Erquinigo        # We can reconstruct the single instruction executed in the first line
2430b697561SWalter Erquinigo        self.expect("n")
244*2238dcc3SJonas Devlieghere        self.expect(
245*2238dcc3SJonas Devlieghere            "thread trace dump instructions -f",
246*2238dcc3SJonas Devlieghere            patterns=[
247*2238dcc3SJonas Devlieghere                f"""thread #1: tid = .*
2480b697561SWalter Erquinigo  a.out`main \+ 4 at main.cpp:2
249*2238dcc3SJonas Devlieghere    2: {ADDRESS_REGEX}    movl"""
250*2238dcc3SJonas Devlieghere            ],
251*2238dcc3SJonas Devlieghere        )
2520b697561SWalter Erquinigo
2530b697561SWalter Erquinigo        # We can reconstruct the instructions up to the second line
2540b697561SWalter Erquinigo        self.expect("n")
255*2238dcc3SJonas Devlieghere        self.expect(
256*2238dcc3SJonas Devlieghere            "thread trace dump instructions -f",
257*2238dcc3SJonas Devlieghere            patterns=[
258*2238dcc3SJonas Devlieghere                f"""thread #1: tid = .*
2590b697561SWalter Erquinigo  a.out`main \+ 4 at main.cpp:2
2602098e2f4SWalter Erquinigo    2: {ADDRESS_REGEX}    movl .*
2610b697561SWalter Erquinigo  a.out`main \+ 11 at main.cpp:4
2622098e2f4SWalter Erquinigo    4: {ADDRESS_REGEX}    movl .*
2632098e2f4SWalter Erquinigo    6: {ADDRESS_REGEX}    jmp  .* ; <\+28> at main.cpp:4
2642098e2f4SWalter Erquinigo    8: {ADDRESS_REGEX}    cmpl .*
265*2238dcc3SJonas Devlieghere    10: {ADDRESS_REGEX}    jle  .* ; <\+20> at main.cpp:5"""
266*2238dcc3SJonas Devlieghere            ],
267*2238dcc3SJonas Devlieghere        )
2680b697561SWalter Erquinigo
269*2238dcc3SJonas Devlieghere        self.expect(
270*2238dcc3SJonas Devlieghere            "thread trace dump instructions",
271*2238dcc3SJonas Devlieghere            patterns=[
272*2238dcc3SJonas Devlieghere                f"""thread #1: tid = .*
273b0aa7076SWalter Erquinigo  a.out`main \+ 32 at main.cpp:4
2742098e2f4SWalter Erquinigo    10: {ADDRESS_REGEX}    jle  .* ; <\+20> at main.cpp:5
2752098e2f4SWalter Erquinigo    8: {ADDRESS_REGEX}    cmpl .*
2762098e2f4SWalter Erquinigo    6: {ADDRESS_REGEX}    jmp  .* ; <\+28> at main.cpp:4
2772098e2f4SWalter Erquinigo    4: {ADDRESS_REGEX}    movl .*
278b0aa7076SWalter Erquinigo  a.out`main \+ 4 at main.cpp:2
279*2238dcc3SJonas Devlieghere    2: {ADDRESS_REGEX}    movl .* """
280*2238dcc3SJonas Devlieghere            ],
281*2238dcc3SJonas Devlieghere        )
282b0aa7076SWalter Erquinigo
2830b697561SWalter Erquinigo        # We stop tracing
2840b697561SWalter Erquinigo        self.expect("thread trace stop")
2850b697561SWalter Erquinigo
2860b697561SWalter Erquinigo        # We can't stop twice
287*2238dcc3SJonas Devlieghere        self.expect(
288*2238dcc3SJonas Devlieghere            "thread trace stop",
289*2238dcc3SJonas Devlieghere            error=True,
290*2238dcc3SJonas Devlieghere            substrs=["error: Thread ", "not currently traced"],
291*2238dcc3SJonas Devlieghere        )
2920b697561SWalter Erquinigo
2930b697561SWalter Erquinigo        # We trace again from scratch, this time letting LLDB to pick the current
2940b697561SWalter Erquinigo        # thread
2950b697561SWalter Erquinigo        self.expect("thread trace start")
2960b697561SWalter Erquinigo        self.expect("n")
297*2238dcc3SJonas Devlieghere        self.expect(
298*2238dcc3SJonas Devlieghere            "thread trace dump instructions -f",
299*2238dcc3SJonas Devlieghere            patterns=[
300*2238dcc3SJonas Devlieghere                f"""thread #1: tid = .*
301b0aa7076SWalter Erquinigo  a.out`main \+ 20 at main.cpp:5
302*2238dcc3SJonas Devlieghere    2: {ADDRESS_REGEX}    xorl"""
303*2238dcc3SJonas Devlieghere            ],
304*2238dcc3SJonas Devlieghere        )
305b0aa7076SWalter Erquinigo
306*2238dcc3SJonas Devlieghere        self.expect(
307*2238dcc3SJonas Devlieghere            "thread trace dump instructions",
308*2238dcc3SJonas Devlieghere            patterns=[
309*2238dcc3SJonas Devlieghere                f"""thread #1: tid = .*
3100b697561SWalter Erquinigo  a.out`main \+ 20 at main.cpp:5
311*2238dcc3SJonas Devlieghere    2: {ADDRESS_REGEX}    xorl"""
312*2238dcc3SJonas Devlieghere            ],
313*2238dcc3SJonas Devlieghere        )
314fb19f11eSWalter Erquinigo
315fb19f11eSWalter Erquinigo        self.expect("c")
316fb19f11eSWalter Erquinigo        # Now the process has finished, so the commands should fail
317*2238dcc3SJonas Devlieghere        self.expect(
318*2238dcc3SJonas Devlieghere            "thread trace start",
319*2238dcc3SJonas Devlieghere            error=True,
320*2238dcc3SJonas Devlieghere            substrs=["error: Process must be launched"],
321*2238dcc3SJonas Devlieghere        )
322fb19f11eSWalter Erquinigo
323*2238dcc3SJonas Devlieghere        self.expect(
324*2238dcc3SJonas Devlieghere            "thread trace stop", error=True, substrs=["error: Process must be launched"]
325*2238dcc3SJonas Devlieghere        )
326a80c6c7dSWalter Erquinigo
327a80c6c7dSWalter Erquinigo        # We should be able to trace the program if we relaunch it
328a80c6c7dSWalter Erquinigo        # For this, we'll trace starting at a different point in the new
329a80c6c7dSWalter Erquinigo        # process.
330a80c6c7dSWalter Erquinigo        self.expect("breakpoint disable")
331a80c6c7dSWalter Erquinigo        self.expect("b main.cpp:4")
332a80c6c7dSWalter Erquinigo        self.expect("r")
333a80c6c7dSWalter Erquinigo        self.expect("thread trace start")
334a80c6c7dSWalter Erquinigo        # We can reconstruct the single instruction executed in the first line
335a80c6c7dSWalter Erquinigo        self.expect("si")
336*2238dcc3SJonas Devlieghere        self.expect(
337*2238dcc3SJonas Devlieghere            "thread trace dump instructions -c 1",
338*2238dcc3SJonas Devlieghere            patterns=[
339*2238dcc3SJonas Devlieghere                f"""thread #1: tid = .*
340*2238dcc3SJonas Devlieghere  a.out`main \+ 11 at main.cpp:4"""
341*2238dcc3SJonas Devlieghere            ],
342*2238dcc3SJonas Devlieghere        )
343