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