xref: /llvm-project/lldb/test/API/commands/trace/TestTraceLoad.py (revision a50ea2f76f993f65c8756067f7ad5a21e560b0c9)
174c93956SWalter Erquinigoimport lldb
2bf9f21a2SWalter Erquinigofrom intelpt_testcase import *
374c93956SWalter Erquinigofrom lldbsuite.test.lldbtest import *
474c93956SWalter Erquinigofrom lldbsuite.test import lldbutil
574c93956SWalter Erquinigofrom lldbsuite.test.decorators import *
674c93956SWalter Erquinigo
72238dcc3SJonas Devlieghere
8bf9f21a2SWalter Erquinigoclass TestTraceLoad(TraceIntelPTTestCaseBase):
974c93956SWalter Erquinigo    NO_DEBUG_INFO_TESTCASE = True
1074c93956SWalter Erquinigo
1150f93679SJakob Johnson    @testSBAPIAndCommands
12a19fcc2bSWalter Erquinigo    def testLoadMultiCoreTrace(self):
13a19fcc2bSWalter Erquinigo        src_dir = self.getSourceDir()
142238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
152238dcc3SJonas Devlieghere            src_dir, "intelpt-multi-core-trace", "trace.json"
162238dcc3SJonas Devlieghere        )
172238dcc3SJonas Devlieghere        self.traceLoad(
182238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]
192238dcc3SJonas Devlieghere        )
202238dcc3SJonas Devlieghere        self.expect(
212238dcc3SJonas Devlieghere            "thread trace dump instructions 2 -t",
222238dcc3SJonas Devlieghere            substrs=[
232238dcc3SJonas Devlieghere                "19526: [19691636.212 ns] (error) decoding truncated: TSC 40450075478109270 exceeds maximum TSC value 40450075477704372, will skip decoding the remaining data of the PSB (skipping 774 of 825 bytes)",
24a19fcc2bSWalter Erquinigo                "m.out`foo() + 65 at multi_thread.cpp:12:21",
252238dcc3SJonas Devlieghere                "9524: [19691632.221 ns] 0x0000000000400ba7    jg     0x400bb3",
262238dcc3SJonas Devlieghere            ],
272238dcc3SJonas Devlieghere        )
282238dcc3SJonas Devlieghere        self.expect(
292238dcc3SJonas Devlieghere            "thread trace dump instructions 3 -t",
302238dcc3SJonas Devlieghere            substrs=[
312238dcc3SJonas Devlieghere                "61831: [19736132.088 ns] 0x0000000000400bd7    addl   $0x1, -0x4(%rbp)",
322238dcc3SJonas Devlieghere                "m.out`bar() + 26 at multi_thread.cpp:20:6",
332238dcc3SJonas Devlieghere            ],
342238dcc3SJonas Devlieghere        )
35a19fcc2bSWalter Erquinigo
362238dcc3SJonas Devlieghere        self.expect(
372238dcc3SJonas Devlieghere            "thread trace dump info --json",
382238dcc3SJonas Devlieghere            substrs=[
392238dcc3SJonas Devlieghere                """{
404a843d92SWalter Erquinigo  "traceTechnology": "intel-pt",
414a843d92SWalter Erquinigo  "threadStats": {
424a843d92SWalter Erquinigo    "tid": 3497234,
434a843d92SWalter Erquinigo    "traceItemsCount": 0,
444a843d92SWalter Erquinigo    "memoryUsage": {
454a843d92SWalter Erquinigo      "totalInBytes": "0",
464a843d92SWalter Erquinigo      "avgPerItemInBytes": null
474a843d92SWalter Erquinigo    },
480466d1dfSymeng    "timingInSeconds": {
492238dcc3SJonas Devlieghere      "Decoding instructions": """,
502238dcc3SJonas Devlieghere                """
510466d1dfSymeng    },
524a843d92SWalter Erquinigo    "events": {
534a843d92SWalter Erquinigo      "totalCount": 0,
544a843d92SWalter Erquinigo      "individualCounts": {}
554a843d92SWalter Erquinigo    },
56c49d14acSWalter Erquinigo    "errors": {
57c49d14acSWalter Erquinigo      "totalCount": 0,
58c49d14acSWalter Erquinigo      "libiptErrors": {},
59c49d14acSWalter Erquinigo      "fatalErrors": 0,
60c49d14acSWalter Erquinigo      "otherErrors": 0
61c49d14acSWalter Erquinigo    },
624a843d92SWalter Erquinigo    "continuousExecutions": 0,
63e17cae07SWalter Erquinigo    "PSBBlocks": 0
644a843d92SWalter Erquinigo  },
654a843d92SWalter Erquinigo  "globalStats": {
664a843d92SWalter Erquinigo    "timingInSeconds": {
674a843d92SWalter Erquinigo      "Context switch and Intel PT traces correlation": 0
684a843d92SWalter Erquinigo    },
694a843d92SWalter Erquinigo    "totalUnattributedPSBBlocks": 0,
704a843d92SWalter Erquinigo    "totalCountinuosExecutions": 153,
714a843d92SWalter Erquinigo    "totalPSBBlocks": 5,
724a843d92SWalter Erquinigo    "totalContinuousExecutions": 153
734a843d92SWalter Erquinigo  }
742238dcc3SJonas Devlieghere}""",
752238dcc3SJonas Devlieghere            ],
762238dcc3SJonas Devlieghere        )
774a843d92SWalter Erquinigo
782238dcc3SJonas Devlieghere        self.expect(
792238dcc3SJonas Devlieghere            "thread trace dump info 2 --json",
802238dcc3SJonas Devlieghere            substrs=[
812238dcc3SJonas Devlieghere                """{
824a843d92SWalter Erquinigo  "traceTechnology": "intel-pt",
834a843d92SWalter Erquinigo  "threadStats": {
844a843d92SWalter Erquinigo    "tid": 3497496,
85*a50ea2f7SNicholas Mosier    "traceItemsCount": 19527,""",
862238dcc3SJonas Devlieghere                """},
870466d1dfSymeng    "timingInSeconds": {
882238dcc3SJonas Devlieghere      "Decoding instructions": """,
892238dcc3SJonas Devlieghere                """
900466d1dfSymeng    },
914a843d92SWalter Erquinigo    "events": {
9217c65e51SJakob Johnson      "totalCount": 5,
934a843d92SWalter Erquinigo      "individualCounts": {
944a843d92SWalter Erquinigo        "software disabled tracing": 1,
95e17cae07SWalter Erquinigo        "trace synchronization point": 1,
96840d861dSWalter Erquinigo        "CPU core changed": 1,
9717c65e51SJakob Johnson        "HW clock tick": 2
984a843d92SWalter Erquinigo      }
994a843d92SWalter Erquinigo    },
100c49d14acSWalter Erquinigo    "errors": {
101c49d14acSWalter Erquinigo      "totalCount": 1,
102c49d14acSWalter Erquinigo      "libiptErrors": {},
103c49d14acSWalter Erquinigo      "fatalErrors": 0,
104c49d14acSWalter Erquinigo      "otherErrors": 1
105c49d14acSWalter Erquinigo    },
1064a843d92SWalter Erquinigo    "continuousExecutions": 1,
107e17cae07SWalter Erquinigo    "PSBBlocks": 1
1084a843d92SWalter Erquinigo  },
1094a843d92SWalter Erquinigo  "globalStats": {
1104a843d92SWalter Erquinigo    "timingInSeconds": {
1112238dcc3SJonas Devlieghere      "Context switch and Intel PT traces correlation": 0""",
1122238dcc3SJonas Devlieghere                """},
1134a843d92SWalter Erquinigo    "totalUnattributedPSBBlocks": 0,
1144a843d92SWalter Erquinigo    "totalCountinuosExecutions": 153,
1154a843d92SWalter Erquinigo    "totalPSBBlocks": 5,
1164a843d92SWalter Erquinigo    "totalContinuousExecutions": 153
1174a843d92SWalter Erquinigo  }
1182238dcc3SJonas Devlieghere}""",
1192238dcc3SJonas Devlieghere            ],
1202238dcc3SJonas Devlieghere        )
1214a843d92SWalter Erquinigo
12250f93679SJakob Johnson    @testSBAPIAndCommands
123b532dd54SWalter Erquinigo    def testLoadCompactMultiCoreTrace(self):
124b532dd54SWalter Erquinigo        src_dir = self.getSourceDir()
1252238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
1262238dcc3SJonas Devlieghere            src_dir, "intelpt-multi-core-trace", "trace.json"
1272238dcc3SJonas Devlieghere        )
1282238dcc3SJonas Devlieghere        self.traceLoad(
1292238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]
1302238dcc3SJonas Devlieghere        )
131b532dd54SWalter Erquinigo
1322238dcc3SJonas Devlieghere        self.expect(
1332238dcc3SJonas Devlieghere            "thread trace dump info 2",
1342238dcc3SJonas Devlieghere            substrs=["Total number of continuous executions found: 153"],
1352238dcc3SJonas Devlieghere        )
136b532dd54SWalter Erquinigo
137b532dd54SWalter Erquinigo        # we'll save the trace in compact format
1382238dcc3SJonas Devlieghere        compact_trace_bundle_dir = os.path.join(
1392238dcc3SJonas Devlieghere            self.getBuildDir(), "intelpt-multi-core-trace-compact"
1402238dcc3SJonas Devlieghere        )
141b532dd54SWalter Erquinigo        self.traceSave(compact_trace_bundle_dir, compact=True)
142b532dd54SWalter Erquinigo
143b532dd54SWalter Erquinigo        # we'll delete the previous target and make sure it's trace object is deleted
144b532dd54SWalter Erquinigo        self.dbg.DeleteTarget(self.dbg.GetTargetAtIndex(0))
1452238dcc3SJonas Devlieghere        self.expect(
1462238dcc3SJonas Devlieghere            "thread trace dump instructions 2 -t",
1472238dcc3SJonas Devlieghere            substrs=["error: invalid target"],
1482238dcc3SJonas Devlieghere            error=True,
1492238dcc3SJonas Devlieghere        )
150b532dd54SWalter Erquinigo
151b532dd54SWalter Erquinigo        # we'll load the compact trace and make sure it works
1522238dcc3SJonas Devlieghere        self.traceLoad(
1532238dcc3SJonas Devlieghere            os.path.join(compact_trace_bundle_dir, "trace.json"), substrs=["intel-pt"]
1542238dcc3SJonas Devlieghere        )
1552238dcc3SJonas Devlieghere        self.expect(
1562238dcc3SJonas Devlieghere            "thread trace dump instructions 2 -t",
1572238dcc3SJonas Devlieghere            substrs=[
158*a50ea2f7SNicholas Mosier                "19526: [19691636.212 ns] (error)",
159b532dd54SWalter Erquinigo                "m.out`foo() + 65 at multi_thread.cpp:12:21",
1602238dcc3SJonas Devlieghere                "19524: [19691632.221 ns] 0x0000000000400ba7    jg     0x400bb3",
1612238dcc3SJonas Devlieghere            ],
1622238dcc3SJonas Devlieghere        )
1632238dcc3SJonas Devlieghere        self.expect(
1642238dcc3SJonas Devlieghere            "thread trace dump instructions 3 -t",
1652238dcc3SJonas Devlieghere            substrs=[
166*a50ea2f7SNicholas Mosier                "61833: [19736136.079 ns] (error)",
16717c65e51SJakob Johnson                "61831: [19736132.088 ns] 0x0000000000400bd7    addl   $0x1, -0x4(%rbp)",
1682238dcc3SJonas Devlieghere                "m.out`bar() + 26 at multi_thread.cpp:20:6",
1692238dcc3SJonas Devlieghere            ],
1702238dcc3SJonas Devlieghere        )
171b532dd54SWalter Erquinigo
172b532dd54SWalter Erquinigo        # This reduced the number of continuous executions to look at
1732238dcc3SJonas Devlieghere        self.expect(
1742238dcc3SJonas Devlieghere            "thread trace dump info 2",
1752238dcc3SJonas Devlieghere            substrs=["Total number of continuous executions found: 3"],
1762238dcc3SJonas Devlieghere        )
177b532dd54SWalter Erquinigo
178b532dd54SWalter Erquinigo        # We clean up for the next run of this test
179b532dd54SWalter Erquinigo        self.dbg.DeleteTarget(self.dbg.GetTargetAtIndex(0))
180b532dd54SWalter Erquinigo
181b532dd54SWalter Erquinigo    @testSBAPIAndCommands
1829f45f23dSWalter Erquinigo    def testLoadMultiCoreTraceWithStringNumbers(self):
1839f45f23dSWalter Erquinigo        src_dir = self.getSourceDir()
1842238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
1852238dcc3SJonas Devlieghere            src_dir, "intelpt-multi-core-trace", "trace_with_string_numbers.json"
1862238dcc3SJonas Devlieghere        )
1872238dcc3SJonas Devlieghere        self.traceLoad(
1882238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]
1892238dcc3SJonas Devlieghere        )
1902238dcc3SJonas Devlieghere        self.expect(
1912238dcc3SJonas Devlieghere            "thread trace dump instructions 2 -t",
1922238dcc3SJonas Devlieghere            substrs=[
193*a50ea2f7SNicholas Mosier                "19526: [19691636.212 ns] (error)",
1949f45f23dSWalter Erquinigo                "m.out`foo() + 65 at multi_thread.cpp:12:21",
1952238dcc3SJonas Devlieghere                "19524: [19691632.221 ns] 0x0000000000400ba7    jg     0x400bb3",
1962238dcc3SJonas Devlieghere            ],
1972238dcc3SJonas Devlieghere        )
1982238dcc3SJonas Devlieghere        self.expect(
1992238dcc3SJonas Devlieghere            "thread trace dump instructions 3 -t",
2002238dcc3SJonas Devlieghere            substrs=[
2012238dcc3SJonas Devlieghere                "61831: [19736132.088 ns] 0x0000000000400bd7    addl   $0x1, -0x4(%rbp)",
2022238dcc3SJonas Devlieghere                "m.out`bar() + 26 at multi_thread.cpp:20:6",
2032238dcc3SJonas Devlieghere            ],
2042238dcc3SJonas Devlieghere        )
2059f45f23dSWalter Erquinigo
20650f93679SJakob Johnson    @testSBAPIAndCommands
207ff15efc1SWalter Erquinigo    def testLoadMultiCoreTraceWithMissingThreads(self):
208ff15efc1SWalter Erquinigo        src_dir = self.getSourceDir()
2092238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
2102238dcc3SJonas Devlieghere            src_dir, "intelpt-multi-core-trace", "trace_missing_threads.json"
2112238dcc3SJonas Devlieghere        )
2122238dcc3SJonas Devlieghere        self.traceLoad(
2132238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]
2142238dcc3SJonas Devlieghere        )
2152238dcc3SJonas Devlieghere        self.expect(
2162238dcc3SJonas Devlieghere            "thread trace dump instructions 3 -t",
2172238dcc3SJonas Devlieghere            substrs=[
218*a50ea2f7SNicholas Mosier                "19526: [19691636.212 ns] (error)",
219ff15efc1SWalter Erquinigo                "m.out`foo() + 65 at multi_thread.cpp:12:21",
2202238dcc3SJonas Devlieghere                "19524: [19691632.221 ns] 0x0000000000400ba7    jg     0x400bb3",
2212238dcc3SJonas Devlieghere            ],
2222238dcc3SJonas Devlieghere        )
2232238dcc3SJonas Devlieghere        self.expect(
2242238dcc3SJonas Devlieghere            "thread trace dump instructions 2 -t",
2252238dcc3SJonas Devlieghere            substrs=[
2262238dcc3SJonas Devlieghere                "61831: [19736132.088 ns] 0x0000000000400bd7    addl   $0x1, -0x4(%rbp)",
2272238dcc3SJonas Devlieghere                "m.out`bar() + 26 at multi_thread.cpp:20:6",
2282238dcc3SJonas Devlieghere            ],
2292238dcc3SJonas Devlieghere        )
230ff15efc1SWalter Erquinigo
23150f93679SJakob Johnson    @testSBAPIAndCommands
23274c93956SWalter Erquinigo    def testLoadTrace(self):
23374c93956SWalter Erquinigo        src_dir = self.getSourceDir()
2342238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
2352238dcc3SJonas Devlieghere            src_dir, "intelpt-trace", "trace.json"
2362238dcc3SJonas Devlieghere        )
2372238dcc3SJonas Devlieghere        self.traceLoad(
2382238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]
2392238dcc3SJonas Devlieghere        )
24074c93956SWalter Erquinigo
24174c93956SWalter Erquinigo        target = self.dbg.GetSelectedTarget()
24274c93956SWalter Erquinigo        process = target.GetProcess()
24374c93956SWalter Erquinigo        self.assertEqual(process.GetProcessID(), 1234)
24474c93956SWalter Erquinigo
24574c93956SWalter Erquinigo        self.assertEqual(process.GetNumThreads(), 1)
24674c93956SWalter Erquinigo        self.assertEqual(process.GetThreadAtIndex(0).GetThreadID(), 3842849)
24774c93956SWalter Erquinigo
24874c93956SWalter Erquinigo        self.assertEqual(target.GetNumModules(), 1)
24974c93956SWalter Erquinigo        module = target.GetModuleAtIndex(0)
25074c93956SWalter Erquinigo        path = module.GetFileSpec()
25174c93956SWalter Erquinigo        self.assertEqual(path.fullpath, os.path.join(src_dir, "intelpt-trace", "a.out"))
25274c93956SWalter Erquinigo        self.assertGreater(module.GetNumSections(), 0)
25374c93956SWalter Erquinigo        self.assertEqual(module.GetSectionAtIndex(0).GetFileAddress(), 0x400000)
25474c93956SWalter Erquinigo
2552238dcc3SJonas Devlieghere        self.assertEqual(
2562238dcc3SJonas Devlieghere            "6AA9A4E2-6F28-2F33-377D-59FECE874C71-5B41261A", module.GetUUIDString()
2572238dcc3SJonas Devlieghere        )
25874c93956SWalter Erquinigo
25926d861cbSWalter Erquinigo        # check that the Process and Thread objects were created correctly
26026d861cbSWalter Erquinigo        self.expect("thread info", substrs=["tid = 3842849"])
26126d861cbSWalter Erquinigo        self.expect("thread list", substrs=["Process 1234 stopped", "tid = 3842849"])
2622238dcc3SJonas Devlieghere        self.expect(
2632238dcc3SJonas Devlieghere            "thread trace dump info",
2642238dcc3SJonas Devlieghere            substrs=[
2652238dcc3SJonas Devlieghere                """thread #1: tid = 3842849
26626d861cbSWalter Erquinigo
2670466d1dfSymeng  Trace technology: intel-pt
2680466d1dfSymeng
2692098e2f4SWalter Erquinigo  Total number of trace items: 28
270d8499590SAlisamar Husain
271bdf3e7e5SWalter Erquinigo  Memory usage:
272*a50ea2f7SNicholas Mosier    Raw trace size: 4 KiB""",
2732238dcc3SJonas Devlieghere                """
274bdf3e7e5SWalter Erquinigo
275059f39d2SWalter Erquinigo  Events:
2762098e2f4SWalter Erquinigo    Number of individual events: 7
277a7d6c3efSWalter Erquinigo      software disabled tracing: 2
2782098e2f4SWalter Erquinigo      hardware disabled tracing: 4
2792238dcc3SJonas Devlieghere      trace synchronization point: 1""",
2802238dcc3SJonas Devlieghere            ],
2812238dcc3SJonas Devlieghere        )
28274c93956SWalter Erquinigo
28350f93679SJakob Johnson    @testSBAPIAndCommands
28474c93956SWalter Erquinigo    def testLoadInvalidTraces(self):
28574c93956SWalter Erquinigo        src_dir = self.getSourceDir()
28650f93679SJakob Johnson
28774c93956SWalter Erquinigo        # We test first an invalid type
2882238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
2892238dcc3SJonas Devlieghere            src_dir, "intelpt-trace", "trace_bad.json"
2902238dcc3SJonas Devlieghere        )
2912238dcc3SJonas Devlieghere        expected_substrs = [
2922238dcc3SJonas Devlieghere            """error: expected object at traceBundle.processes[0]
29374c93956SWalter Erquinigo
294bddebca6SWalter ErquinigoContext:
295bddebca6SWalter Erquinigo{
296fc5ef57cSWalter Erquinigo  "cpuInfo": { ... },
297bddebca6SWalter Erquinigo  "processes": [
298bddebca6SWalter Erquinigo    /* error: expected object */
299bddebca6SWalter Erquinigo    123
300bddebca6SWalter Erquinigo  ],
301fc5ef57cSWalter Erquinigo  "type": "intel-pt"
302bddebca6SWalter Erquinigo}
303bddebca6SWalter Erquinigo
304bddebca6SWalter ErquinigoSchema:
305bddebca6SWalter Erquinigo{
306bddebca6SWalter Erquinigo  "type": "intel-pt",
3070b697561SWalter Erquinigo  "cpuInfo": {
308fc5ef57cSWalter Erquinigo    // CPU information gotten from, for example, /proc/cpuinfo.
309fc5ef57cSWalter Erquinigo
310fc5ef57cSWalter Erquinigo    "vendor": "GenuineIntel" | "unknown",
311bddebca6SWalter Erquinigo    "family": integer,
312bddebca6SWalter Erquinigo    "model": integer,
313bddebca6SWalter Erquinigo    "stepping": integer
3142238dcc3SJonas Devlieghere  },"""
3152238dcc3SJonas Devlieghere        ]
3162238dcc3SJonas Devlieghere        self.traceLoad(
3172238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path,
3182238dcc3SJonas Devlieghere            error=True,
3192238dcc3SJonas Devlieghere            substrs=expected_substrs,
3202238dcc3SJonas Devlieghere        )
321bddebca6SWalter Erquinigo
322b8dcd0baSWalter Erquinigo        # Now we test a wrong cpu family field in the global bundle description file
3232238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
3242238dcc3SJonas Devlieghere            src_dir, "intelpt-trace", "trace_bad2.json"
3252238dcc3SJonas Devlieghere        )
3262238dcc3SJonas Devlieghere        expected_substrs = [
3272238dcc3SJonas Devlieghere            "error: expected uint64_t at traceBundle.cpuInfo.family",
3282238dcc3SJonas Devlieghere            "Context",
3292238dcc3SJonas Devlieghere            "Schema",
3302238dcc3SJonas Devlieghere        ]
3312238dcc3SJonas Devlieghere        self.traceLoad(
3322238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path,
3332238dcc3SJonas Devlieghere            error=True,
3342238dcc3SJonas Devlieghere            substrs=expected_substrs,
3352238dcc3SJonas Devlieghere        )
336bddebca6SWalter Erquinigo
337bddebca6SWalter Erquinigo        # Now we test a missing field in the intel-pt settings
3382238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
3392238dcc3SJonas Devlieghere            src_dir, "intelpt-trace", "trace_bad4.json"
3402238dcc3SJonas Devlieghere        )
3412238dcc3SJonas Devlieghere        expected_substrs = [
3422238dcc3SJonas Devlieghere            """error: missing value at traceBundle.cpuInfo.family
343bddebca6SWalter Erquinigo
344bddebca6SWalter ErquinigoContext:
345bddebca6SWalter Erquinigo{
3460b697561SWalter Erquinigo  "cpuInfo": /* error: missing value */ {
347bddebca6SWalter Erquinigo    "model": 79,
348bddebca6SWalter Erquinigo    "stepping": 1,
349fc5ef57cSWalter Erquinigo    "vendor": "GenuineIntel"
350bddebca6SWalter Erquinigo  },
351fc5ef57cSWalter Erquinigo  "processes": [],
352bddebca6SWalter Erquinigo  "type": "intel-pt"
3532238dcc3SJonas Devlieghere}""",
3542238dcc3SJonas Devlieghere            "Schema",
3552238dcc3SJonas Devlieghere        ]
3562238dcc3SJonas Devlieghere        self.traceLoad(
3572238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path,
3582238dcc3SJonas Devlieghere            error=True,
3592238dcc3SJonas Devlieghere            substrs=expected_substrs,
3602238dcc3SJonas Devlieghere        )
361bddebca6SWalter Erquinigo
362bddebca6SWalter Erquinigo        # Now we test an incorrect load address in the intel-pt settings
3632238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
3642238dcc3SJonas Devlieghere            src_dir, "intelpt-trace", "trace_bad5.json"
3652238dcc3SJonas Devlieghere        )
3662238dcc3SJonas Devlieghere        expected_substrs = [
3672238dcc3SJonas Devlieghere            "error: missing value at traceBundle.processes[1].pid",
3682238dcc3SJonas Devlieghere            "Schema",
3692238dcc3SJonas Devlieghere        ]
3702238dcc3SJonas Devlieghere        self.traceLoad(
3712238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path,
3722238dcc3SJonas Devlieghere            error=True,
3732238dcc3SJonas Devlieghere            substrs=expected_substrs,
3742238dcc3SJonas Devlieghere        )
37574c93956SWalter Erquinigo
37674c93956SWalter Erquinigo        # The following wrong schema will have a valid target and an invalid one. In the case of failure,
37774c93956SWalter Erquinigo        # no targets should be created.
37874c93956SWalter Erquinigo        self.assertEqual(self.dbg.GetNumTargets(), 0)
3792238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
3802238dcc3SJonas Devlieghere            src_dir, "intelpt-trace", "trace_bad3.json"
3812238dcc3SJonas Devlieghere        )
3822238dcc3SJonas Devlieghere        expected_substrs = ["error: missing value at traceBundle.processes[1].pid"]
3832238dcc3SJonas Devlieghere        self.traceLoad(
3842238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path,
3852238dcc3SJonas Devlieghere            error=True,
3862238dcc3SJonas Devlieghere            substrs=expected_substrs,
3872238dcc3SJonas Devlieghere        )
38874c93956SWalter Erquinigo        self.assertEqual(self.dbg.GetNumTargets(), 0)
389f9b4ea0cSJakob Johnson
390f9b4ea0cSJakob Johnson    def testLoadTraceCursor(self):
391f9b4ea0cSJakob Johnson        src_dir = self.getSourceDir()
3922238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
3932238dcc3SJonas Devlieghere            src_dir, "intelpt-multi-core-trace", "trace.json"
3942238dcc3SJonas Devlieghere        )
395f9b4ea0cSJakob Johnson        traceDescriptionFile = lldb.SBFileSpec(trace_description_file_path, True)
396f9b4ea0cSJakob Johnson
397f9b4ea0cSJakob Johnson        error = lldb.SBError()
398f9b4ea0cSJakob Johnson        trace = self.dbg.LoadTraceFromFile(error, traceDescriptionFile)
399f9b4ea0cSJakob Johnson        self.assertSBError(error)
400f9b4ea0cSJakob Johnson
401f9b4ea0cSJakob Johnson        target = self.dbg.GetSelectedTarget()
402f9b4ea0cSJakob Johnson        process = target.process
403f9b4ea0cSJakob Johnson
404f9b4ea0cSJakob Johnson        # 1. Test some expected items of thread 1's trace cursor.
405f9b4ea0cSJakob Johnson        thread1 = process.threads[1]
406f9b4ea0cSJakob Johnson        cursor = trace.CreateNewCursor(error, thread1)
407f9b4ea0cSJakob Johnson        self.assertTrue(cursor)
408f9b4ea0cSJakob Johnson        self.assertTrue(cursor.HasValue())
409f9b4ea0cSJakob Johnson        cursor.Seek(0, lldb.eTraceCursorSeekTypeBeginning)
410f9b4ea0cSJakob Johnson        cursor.SetForwards(True)
411f9b4ea0cSJakob Johnson
412f9b4ea0cSJakob Johnson        self.assertTrue(cursor.IsEvent())
413f9b4ea0cSJakob Johnson        self.assertEqual(cursor.GetEventTypeAsString(), "HW clock tick")
414f9b4ea0cSJakob Johnson        self.assertEqual(cursor.GetCPU(), lldb.LLDB_INVALID_CPU_ID)
415f9b4ea0cSJakob Johnson
416f9b4ea0cSJakob Johnson        cursor.Next()
417f9b4ea0cSJakob Johnson
418f9b4ea0cSJakob Johnson        self.assertTrue(cursor.IsEvent())
419f9b4ea0cSJakob Johnson        self.assertEqual(cursor.GetEventTypeAsString(), "CPU core changed")
420f9b4ea0cSJakob Johnson        self.assertEqual(cursor.GetCPU(), 51)
421f9b4ea0cSJakob Johnson
42217c65e51SJakob Johnson        cursor.GoToId(19526)
423f9b4ea0cSJakob Johnson
424f9b4ea0cSJakob Johnson        self.assertTrue(cursor.IsError())
4252238dcc3SJonas Devlieghere        self.assertEqual(
4262238dcc3SJonas Devlieghere            cursor.GetError(),
4272238dcc3SJonas Devlieghere            "decoding truncated: TSC 40450075478109270 exceeds maximum TSC value 40450075477704372, will skip decoding the remaining data of the PSB (skipping 774 of 825 bytes)",
4282238dcc3SJonas Devlieghere        )
429f9b4ea0cSJakob Johnson
430e17cae07SWalter Erquinigo        cursor.GoToId(19524)
431f9b4ea0cSJakob Johnson
432f9b4ea0cSJakob Johnson        self.assertTrue(cursor.IsInstruction())
433e17cae07SWalter Erquinigo        self.assertEqual(cursor.GetLoadAddress(), 0x400BA7)
434f9b4ea0cSJakob Johnson
435f9b4ea0cSJakob Johnson        # Helper function to check equality of the current item of two trace cursors.
436f9b4ea0cSJakob Johnson        def assertCurrentTraceCursorItemEqual(lhs, rhs):
437f9b4ea0cSJakob Johnson            self.assertTrue(lhs.HasValue() and rhs.HasValue())
438f9b4ea0cSJakob Johnson
439f9b4ea0cSJakob Johnson            self.assertEqual(lhs.GetId(), rhs.GetId())
440f9b4ea0cSJakob Johnson            self.assertEqual(lhs.GetItemKind(), rhs.GetItemKind())
441f9b4ea0cSJakob Johnson            if lhs.IsError():
442f9b4ea0cSJakob Johnson                self.assertEqual(lhs.GetError(), rhs.GetError())
443f9b4ea0cSJakob Johnson            elif lhs.IsEvent():
444f9b4ea0cSJakob Johnson                self.assertEqual(lhs.GetEventType(), rhs.GetEventType())
445f9b4ea0cSJakob Johnson                self.assertEqual(lhs.GetEventTypeAsString(), rhs.GetEventTypeAsString())
446f9b4ea0cSJakob Johnson            elif lhs.IsInstruction():
447f9b4ea0cSJakob Johnson                self.assertEqual(lhs.GetLoadAddress(), rhs.GetLoadAddress())
448f9b4ea0cSJakob Johnson            else:
449f9b4ea0cSJakob Johnson                self.fail("Unknown trace item kind")
450f9b4ea0cSJakob Johnson
451f9b4ea0cSJakob Johnson        for thread in process.threads:
452f9b4ea0cSJakob Johnson            sequentialTraversalCursor = trace.CreateNewCursor(error, thread)
453f9b4ea0cSJakob Johnson            self.assertSBError(error)
454f9b4ea0cSJakob Johnson            # Skip threads with no trace items
455f9b4ea0cSJakob Johnson            if not sequentialTraversalCursor.HasValue():
456f9b4ea0cSJakob Johnson                continue
457f9b4ea0cSJakob Johnson
458f9b4ea0cSJakob Johnson            # 2. Test "End" boundary of the trace by advancing past the trace's last item.
459f9b4ea0cSJakob Johnson            sequentialTraversalCursor.Seek(0, lldb.eTraceCursorSeekTypeEnd)
460f9b4ea0cSJakob Johnson            self.assertTrue(sequentialTraversalCursor.HasValue())
461f9b4ea0cSJakob Johnson            sequentialTraversalCursor.SetForwards(True)
462f9b4ea0cSJakob Johnson            sequentialTraversalCursor.Next()
463f9b4ea0cSJakob Johnson            self.assertFalse(sequentialTraversalCursor.HasValue())
464f9b4ea0cSJakob Johnson
465f9b4ea0cSJakob Johnson            # 3. Test sequential traversal using sequential access API (ie Next())
466f9b4ea0cSJakob Johnson            # and random access API (ie GoToId()) simultaneously.
467f9b4ea0cSJakob Johnson            randomAccessCursor = trace.CreateNewCursor(error, thread)
468f9b4ea0cSJakob Johnson            self.assertSBError(error)
469f9b4ea0cSJakob Johnson            # Reset the sequential cursor
470f9b4ea0cSJakob Johnson            sequentialTraversalCursor.Seek(0, lldb.eTraceCursorSeekTypeBeginning)
471f9b4ea0cSJakob Johnson            sequentialTraversalCursor.SetForwards(True)
472f9b4ea0cSJakob Johnson            self.assertTrue(sequentialTraversalCursor.IsForwards())
473f9b4ea0cSJakob Johnson
474f9b4ea0cSJakob Johnson            while sequentialTraversalCursor.HasValue():
475f9b4ea0cSJakob Johnson                itemId = sequentialTraversalCursor.GetId()
476f9b4ea0cSJakob Johnson                randomAccessCursor.GoToId(itemId)
4772238dcc3SJonas Devlieghere                assertCurrentTraceCursorItemEqual(
4782238dcc3SJonas Devlieghere                    sequentialTraversalCursor, randomAccessCursor
4792238dcc3SJonas Devlieghere                )
480f9b4ea0cSJakob Johnson                sequentialTraversalCursor.Next()
481f9b4ea0cSJakob Johnson
482f9b4ea0cSJakob Johnson            # 4. Test a random access with random access API (ie Seek()) and
483f9b4ea0cSJakob Johnson            # sequential access API (ie consecutive calls to Next()).
484f9b4ea0cSJakob Johnson            TEST_SEEK_ID = 3
485f9b4ea0cSJakob Johnson            randomAccessCursor.GoToId(TEST_SEEK_ID)
486f9b4ea0cSJakob Johnson            # Reset the sequential cursor
487f9b4ea0cSJakob Johnson            sequentialTraversalCursor.Seek(0, lldb.eTraceCursorSeekTypeBeginning)
488f9b4ea0cSJakob Johnson            sequentialTraversalCursor.SetForwards(True)
4892238dcc3SJonas Devlieghere            for _ in range(TEST_SEEK_ID):
4902238dcc3SJonas Devlieghere                sequentialTraversalCursor.Next()
4912238dcc3SJonas Devlieghere            assertCurrentTraceCursorItemEqual(
4922238dcc3SJonas Devlieghere                sequentialTraversalCursor, randomAccessCursor
4932238dcc3SJonas Devlieghere            )
494f9b4ea0cSJakob Johnson
4956fb744beSWalter Erquinigo    @testSBAPIAndCommands
4966fb744beSWalter Erquinigo    def testLoadKernelTrace(self):
4976fb744beSWalter Erquinigo        # kernel section without loadAddress (using default loadAddress).
4986fb744beSWalter Erquinigo        src_dir = self.getSourceDir()
4992238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
5002238dcc3SJonas Devlieghere            src_dir, "intelpt-kernel-trace", "trace.json"
5012238dcc3SJonas Devlieghere        )
5022238dcc3SJonas Devlieghere        self.traceLoad(
5032238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]
5042238dcc3SJonas Devlieghere        )
505f9b4ea0cSJakob Johnson
5066fb744beSWalter Erquinigo        self.expect("image list", substrs=["0xffffffff81000000", "modules/m.out"])
507f9b4ea0cSJakob Johnson
5082238dcc3SJonas Devlieghere        self.expect(
5092238dcc3SJonas Devlieghere            "thread list",
5102238dcc3SJonas Devlieghere            substrs=[
5116fb744beSWalter Erquinigo                "Process 1 stopped",
5126fb744beSWalter Erquinigo                "* thread #1: tid = 0x002d",
5132238dcc3SJonas Devlieghere                "  thread #2: tid = 0x0033",
5142238dcc3SJonas Devlieghere            ],
5152238dcc3SJonas Devlieghere        )
516f9b4ea0cSJakob Johnson
5176fb744beSWalter Erquinigo        # kernel section with custom loadAddress.
5182238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
5192238dcc3SJonas Devlieghere            src_dir, "intelpt-kernel-trace", "trace_with_loadAddress.json"
5202238dcc3SJonas Devlieghere        )
5212238dcc3SJonas Devlieghere        self.traceLoad(
5222238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path, substrs=["intel-pt"]
5232238dcc3SJonas Devlieghere        )
524f9b4ea0cSJakob Johnson
5256fb744beSWalter Erquinigo        self.expect("image list", substrs=["0x400000", "modules/m.out"])
526f9b4ea0cSJakob Johnson
5276fb744beSWalter Erquinigo    @testSBAPIAndCommands
5286fb744beSWalter Erquinigo    def testLoadInvalidKernelTrace(self):
5296fb744beSWalter Erquinigo        src_dir = self.getSourceDir()
530f9b4ea0cSJakob Johnson
5316fb744beSWalter Erquinigo        # Test kernel section with non-empty processeses section.
5322238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
5332238dcc3SJonas Devlieghere            src_dir, "intelpt-kernel-trace", "trace_kernel_with_process.json"
5342238dcc3SJonas Devlieghere        )
5352238dcc3SJonas Devlieghere        expected_substrs = [
5362238dcc3SJonas Devlieghere            'error: "processes" must be empty when "kernel" is provided when parsing traceBundle'
5372238dcc3SJonas Devlieghere        ]
5382238dcc3SJonas Devlieghere        self.traceLoad(
5392238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path,
5402238dcc3SJonas Devlieghere            error=True,
5412238dcc3SJonas Devlieghere            substrs=expected_substrs,
5422238dcc3SJonas Devlieghere        )
543f9b4ea0cSJakob Johnson
5446fb744beSWalter Erquinigo        # Test kernel section without cpus section.
5452238dcc3SJonas Devlieghere        trace_description_file_path = os.path.join(
5462238dcc3SJonas Devlieghere            src_dir, "intelpt-kernel-trace", "trace_kernel_wo_cpus.json"
5472238dcc3SJonas Devlieghere        )
5482238dcc3SJonas Devlieghere        expected_substrs = [
5492238dcc3SJonas Devlieghere            'error: "cpus" is required when "kernel" is provided when parsing traceBundle'
5502238dcc3SJonas Devlieghere        ]
5512238dcc3SJonas Devlieghere        self.traceLoad(
5522238dcc3SJonas Devlieghere            traceDescriptionFilePath=trace_description_file_path,
5532238dcc3SJonas Devlieghere            error=True,
5542238dcc3SJonas Devlieghere            substrs=expected_substrs,
5552238dcc3SJonas Devlieghere        )
556