brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · 017f5c8 Raw
227 lines · python
1import lldb2import json3from intelpt_testcase import *4from lldbsuite.test.lldbtest import *5from lldbsuite.test import lldbutil6from lldbsuite.test.decorators import *7 8 9@skipIfNoIntelPT10class TestTraceStartStopMultipleThreads(TraceIntelPTTestCaseBase):11    @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))12    @testSBAPIAndCommands13    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 thread30        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    @testSBAPIAndCommands37    def testStartMultipleLiveThreadsWithStops(self):38        self.build()39        exe = self.getBuildArtifact("a.out")40        self.dbg.CreateTarget(exe)41 42        self.expect("b main")43        self.expect("b 6")44        self.expect("b 11")45 46        self.expect("r")47 48        self.traceStartProcess()49 50        # We'll see here the first thread51        self.expect("continue")52 53        # We are in thread 254        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 all58        self.expect("thread trace stop all")59 60        # The trace is still in memory61        self.expect("thread trace dump instructions 2", substrs=["main.cpp:9"])62 63        # We'll stop at the next breakpoint in thread 3, thread 2 and 3 will be alive, but only 3 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        self.expect(68            "thread trace dump instructions 1", substrs=["not traced"], error=True69        )70        self.expect(71            "thread trace dump instructions 2", substrs=["not traced"], error=True72        )73 74        self.traceStopProcess()75 76    @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))77    def testStartMultipleLiveThreadsWithThreadStartAll(self):78        self.build()79        exe = self.getBuildArtifact("a.out")80        target = self.dbg.CreateTarget(exe)81 82        self.expect("b main")83        self.expect("b 6")84        self.expect("b 11")85 86        self.expect("r")87 88        self.expect("continue")89        # We are in thread 290        self.expect("thread trace start all")91        # Now we have instructions in thread's 2 trace92        self.expect("n")93 94        self.expect("thread trace dump instructions 2", substrs=["main.cpp:11"])95 96        # We stop tracing all97        self.runCmd("thread trace stop all")98 99        # The trace is still in memory100        self.expect("thread trace dump instructions 2", substrs=["main.cpp:11"])101 102        # We'll stop at the next breakpoint in thread 3, and nothing should be traced103        self.expect("continue")104        self.expect(105            "thread trace dump instructions 3", substrs=["not traced"], error=True106        )107        self.expect(108            "thread trace dump instructions 1", substrs=["not traced"], error=True109        )110        self.expect(111            "thread trace dump instructions 2", substrs=["not traced"], error=True112        )113 114    @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))115    @testSBAPIAndCommands116    def testStartMultipleLiveThreadsWithSmallTotalLimit(self):117        self.build()118        exe = self.getBuildArtifact("a.out")119 120        self.dbg.CreateTarget(exe)121 122        self.expect("b main")123        self.expect("r")124 125        # trace the entire process with enough total size for 1 thread trace126        self.traceStartProcess(processBufferSizeLimit=5000)127 128        # we get the stop event when trace 2 appears and can't be traced129        self.expect("c", substrs=["Thread", "can't be traced"])130        # we get the stop event when trace 3 appears and can't be traced131        self.expect("c", substrs=["Thread", "can't be traced"])132 133        self.traceStopProcess()134 135    @skipIf(oslist=no_match(["linux"]), archs=no_match(["i386", "x86_64"]))136    @testSBAPIAndCommands137    def testStartPerCpuSession(self):138        self.skipIfPerCpuTracingIsNotSupported()139 140        self.build()141        exe = self.getBuildArtifact("a.out")142        self.dbg.CreateTarget(exe)143 144        self.expect("b main")145        self.expect("r")146 147        # We should fail if we hit the total buffer limit. Useful if the number148        # of cpus is huge.149        self.traceStartProcess(150            error="True",151            processBufferSizeLimit=100,152            perCpuTracing=True,153            substrs=[154                "The process can't be traced because the process trace size "155                "limit has been reached. Consider retracing with a higher limit."156            ],157        )158 159        self.traceStartProcess(perCpuTracing=True)160        self.traceStopProcess()161 162        self.traceStartProcess(perCpuTracing=True)163        # We can't support multiple per-cpu tracing sessions.164        self.traceStartProcess(165            error=True,166            perCpuTracing=True,167            substrs=["Process currently traced. Stop process tracing first"],168        )169 170        # We can't support tracing per thread is per cpu is enabled.171        self.traceStartThread(172            error="True", substrs=["Thread with tid ", "is currently traced"]173        )174 175        # We can't stop individual thread when per cpu is enabled.176        self.traceStopThread(177            error="True",178            substrs=[179                "Can't stop tracing an individual thread when per-cpu process tracing is enabled"180            ],181        )182 183        # We move forward a little bit to collect some data184        self.expect("b 19")185        self.expect("c")186 187        # We will assert that the trace state will contain valid context switch and intel pt trace buffer entries.188        # Besides that, we need to get tsc-to-nanos conversion information.189 190        # We first parse the json response from the custom packet191        self.runCmd(192            """process plugin packet send 'jLLDBTraceGetState:{"type":"intel-pt"}]'"""193        )194        response_header = "response: "195        output = None196        for line in self.res.GetOutput().splitlines():197            if line.find(response_header) != -1:198                response = line[199                    line.find(response_header) + len(response_header) :200                ].strip()201                output = json.loads(response)202 203        self.assertIsNotNone(output)204        self.assertIn("cpus", output)205        self.assertIn("tscPerfZeroConversion", output)206        found_non_empty_context_switch = False207 208        for cpu in output["cpus"]:209            context_switch_size = None210            ipt_trace_size = None211            for binary_data in cpu["binaryData"]:212                if binary_data["kind"] == "iptTrace":213                    ipt_trace_size = binary_data["size"]214                elif binary_data["kind"] == "perfContextSwitchTrace":215                    context_switch_size = binary_data["size"]216            self.assertIsNotNone(context_switch_size)217            self.assertIsNotNone(ipt_trace_size)218            if context_switch_size > 0:219                found_non_empty_context_switch = True220 221        # We must have captured the context switch of when the target resumed222        self.assertTrue(found_non_empty_context_switch)223 224        self.expect("thread trace dump instructions")225 226        self.traceStopProcess()227