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 self.traceStopProcess() 34 35 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 36 @testSBAPIAndCommands 37 def testStartMultipleLiveThreadsWithStops(self): 38 self.build() 39 exe = self.getBuildArtifact("a.out") 40 41 self.dbg.CreateTarget(exe) 42 43 self.expect("b main") 44 self.expect("b 6") 45 self.expect("b 11") 46 47 self.expect("r") 48 self.traceStartProcess() 49 50 # We'll see here the first thread 51 self.expect("continue") 52 53 # We are in thread 2 54 self.expect("thread trace dump instructions", substrs=['main.cpp:9']) 55 self.expect("thread trace dump instructions 2", substrs=['main.cpp:9']) 56 57 # We stop tracing it 58 self.expect("thread trace stop 2") 59 60 # The trace is still in memory 61 self.expect("thread trace dump instructions 2", substrs=['main.cpp:9']) 62 63 # We'll stop at the next breakpoint, thread 2 will be still alive, but not traced. Thread 3 will be traced 64 self.expect("continue") 65 self.expect("thread trace dump instructions", substrs=['main.cpp:4']) 66 self.expect("thread trace dump instructions 3", substrs=['main.cpp:4']) 67 68 self.expect("thread trace dump instructions 2", substrs=['not traced']) 69 70 self.traceStopProcess() 71 72 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 73 @testSBAPIAndCommands 74 def testStartMultipleLiveThreadsWithStops(self): 75 self.build() 76 exe = self.getBuildArtifact("a.out") 77 self.dbg.CreateTarget(exe) 78 79 self.expect("b main") 80 self.expect("b 6") 81 self.expect("b 11") 82 83 self.expect("r") 84 85 self.traceStartProcess() 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 self.traceStopProcess() 108 109 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 110 def testStartMultipleLiveThreadsWithThreadStartAll(self): 111 self.build() 112 exe = self.getBuildArtifact("a.out") 113 target = self.dbg.CreateTarget(exe) 114 115 self.expect("b main") 116 self.expect("b 6") 117 self.expect("b 11") 118 119 self.expect("r") 120 121 self.expect("continue") 122 # We are in thread 2 123 self.expect("thread trace start all") 124 # Now we have instructions in thread's 2 trace 125 self.expect("n") 126 127 self.expect("thread trace dump instructions 2", substrs=['main.cpp:11']) 128 129 # We stop tracing all 130 self.runCmd("thread trace stop all") 131 132 # The trace is still in memory 133 self.expect("thread trace dump instructions 2", substrs=['main.cpp:11']) 134 135 # We'll stop at the next breakpoint in thread 3, and nothing should be traced 136 self.expect("continue") 137 self.expect("thread trace dump instructions 3", substrs=['not traced']) 138 self.expect("thread trace dump instructions 1", substrs=['not traced']) 139 self.expect("thread trace dump instructions 2", substrs=['not traced']) 140 141 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 142 @testSBAPIAndCommands 143 def testStartMultipleLiveThreadsWithSmallTotalLimit(self): 144 self.build() 145 exe = self.getBuildArtifact("a.out") 146 147 self.dbg.CreateTarget(exe) 148 149 self.expect("b main") 150 self.expect("r") 151 152 # trace the entire process with enough total size for 1 thread trace 153 self.traceStartProcess(processBufferSizeLimit=5000) 154 155 # we get the stop event when trace 2 appears and can't be traced 156 self.expect("c", substrs=['Thread', "can't be traced"]) 157 # we get the stop event when trace 3 appears and can't be traced 158 self.expect("c", substrs=['Thread', "can't be traced"]) 159 160 self.traceStopProcess() 161 162 @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64'])) 163 @testSBAPIAndCommands 164 def testStartPerCoreSession(self): 165 self.skipIfPerCoreTracingIsNotSupported() 166 167 self.build() 168 exe = self.getBuildArtifact("a.out") 169 self.dbg.CreateTarget(exe) 170 171 self.expect("b main") 172 self.expect("r") 173 174 # We should fail if we hit the total buffer limit. Useful if the number 175 # of cores is huge. 176 self.traceStartProcess(error="True", processBufferSizeLimit=100, 177 perCoreTracing=True, 178 substrs=["The process can't be traced because the process trace size " 179 "limit has been reached. Consider retracing with a higher limit."]) 180 181 self.traceStartProcess(perCoreTracing=True) 182 self.traceStopProcess() 183 184 self.traceStartProcess(perCoreTracing=True) 185 # We can't support multiple per-core tracing sessions. 186 self.traceStartProcess(error=True, perCoreTracing=True, 187 substrs=["Process currently traced. Stop process tracing first"]) 188 189 # We can't support tracing per thread is per core is enabled. 190 self.traceStartThread( 191 error="True", 192 substrs=["Process currently traced with per-core tracing. Stop process tracing first"]) 193 194 # We can't stop individual thread when per core is enabled. 195 self.traceStopThread(error="True", 196 substrs=["Can't stop tracing an individual thread when per-core process tracing is enabled"]) 197 198 # The GetState packet should return trace buffers per core and at least one traced thread 199 self.expect("""process plugin packet send 'jLLDBTraceGetState:{"type":"intel-pt"}]'""", 200 substrs=['''[{"kind":"traceBuffer","size":4096}],"coreId":''', '"tid":']) 201 202 self.traceStopProcess() 203