15b4100ccSJohn Harrison""" 25b4100ccSJohn HarrisonTest lldb-dap stackTrace request with an extended backtrace thread. 35b4100ccSJohn Harrison""" 45b4100ccSJohn Harrison 55b4100ccSJohn Harrison 65b4100ccSJohn Harrisonimport os 75b4100ccSJohn Harrison 85b4100ccSJohn Harrisonimport lldbdap_testcase 95b4100ccSJohn Harrisonfrom lldbsuite.test.decorators import * 105b4100ccSJohn Harrisonfrom lldbsuite.test.lldbtest import * 115b4100ccSJohn Harrisonfrom lldbsuite.test.lldbplatformutil import * 125b4100ccSJohn Harrison 135b4100ccSJohn Harrison 145b4100ccSJohn Harrisonclass TestDAP_extendedStackTrace(lldbdap_testcase.DAPTestCaseBase): 155b4100ccSJohn Harrison @skipUnlessDarwin 165b4100ccSJohn Harrison def test_stackTrace(self): 175b4100ccSJohn Harrison """ 185b4100ccSJohn Harrison Tests the 'stackTrace' packet on a thread with an extended backtrace. 195b4100ccSJohn Harrison """ 205b4100ccSJohn Harrison backtrace_recording_lib = findBacktraceRecordingDylib() 215b4100ccSJohn Harrison if not backtrace_recording_lib: 225b4100ccSJohn Harrison self.skipTest( 235b4100ccSJohn Harrison "Skipped because libBacktraceRecording.dylib was present on the system." 245b4100ccSJohn Harrison ) 255b4100ccSJohn Harrison 265b4100ccSJohn Harrison if not os.path.isfile("/usr/lib/system/introspection/libdispatch.dylib"): 275b4100ccSJohn Harrison self.skipTest( 285b4100ccSJohn Harrison "Skipped because introspection libdispatch dylib is not present." 295b4100ccSJohn Harrison ) 305b4100ccSJohn Harrison 315b4100ccSJohn Harrison program = self.getBuildArtifact("a.out") 325b4100ccSJohn Harrison 335b4100ccSJohn Harrison self.build_and_launch( 345b4100ccSJohn Harrison program, 355b4100ccSJohn Harrison env=[ 365b4100ccSJohn Harrison "DYLD_LIBRARY_PATH=/usr/lib/system/introspection", 375b4100ccSJohn Harrison "DYLD_INSERT_LIBRARIES=" + backtrace_recording_lib, 385b4100ccSJohn Harrison ], 39*19ecdedcSAdrian Vogelsgesang displayExtendedBacktrace=True, 405b4100ccSJohn Harrison ) 415b4100ccSJohn Harrison source = "main.m" 425b4100ccSJohn Harrison breakpoint = line_number(source, "breakpoint 1") 435b4100ccSJohn Harrison lines = [breakpoint] 445b4100ccSJohn Harrison 455b4100ccSJohn Harrison breakpoint_ids = self.set_source_breakpoints(source, lines) 465b4100ccSJohn Harrison self.assertEqual( 475b4100ccSJohn Harrison len(breakpoint_ids), len(lines), "expect correct number of breakpoints" 485b4100ccSJohn Harrison ) 495b4100ccSJohn Harrison 505b4100ccSJohn Harrison events = self.continue_to_next_stop() 515b4100ccSJohn Harrison 525b4100ccSJohn Harrison stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount( 535b4100ccSJohn Harrison threadId=events[0]["body"]["threadId"] 545b4100ccSJohn Harrison ) 555b4100ccSJohn Harrison self.assertGreaterEqual(len(stackFrames), 3, "expect >= 3 frames") 565b4100ccSJohn Harrison self.assertEqual(len(stackFrames), totalFrames) 575b4100ccSJohn Harrison self.assertEqual(stackFrames[0]["name"], "one") 585b4100ccSJohn Harrison self.assertEqual(stackFrames[1]["name"], "two") 595b4100ccSJohn Harrison self.assertEqual(stackFrames[2]["name"], "three") 605b4100ccSJohn Harrison 615b4100ccSJohn Harrison stackLabels = [ 625b4100ccSJohn Harrison (i, frame) 635b4100ccSJohn Harrison for i, frame in enumerate(stackFrames) 645b4100ccSJohn Harrison if frame.get("presentationHint", "") == "label" 655b4100ccSJohn Harrison ] 665b4100ccSJohn Harrison self.assertEqual(len(stackLabels), 2, "expected two label stack frames") 675b4100ccSJohn Harrison self.assertRegex( 685b4100ccSJohn Harrison stackLabels[0][1]["name"], 695b4100ccSJohn Harrison "Enqueued from com.apple.root.default-qos \(Thread \d\)", 705b4100ccSJohn Harrison ) 715b4100ccSJohn Harrison self.assertRegex( 725b4100ccSJohn Harrison stackLabels[1][1]["name"], 735b4100ccSJohn Harrison "Enqueued from com.apple.main-thread \(Thread \d\)", 745b4100ccSJohn Harrison ) 755b4100ccSJohn Harrison 765b4100ccSJohn Harrison for i, frame in stackLabels: 775b4100ccSJohn Harrison # Ensure requesting startFrame+levels across thread backtraces works as expected. 785b4100ccSJohn Harrison stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount( 795b4100ccSJohn Harrison threadId=events[0]["body"]["threadId"], startFrame=i - 1, levels=3 805b4100ccSJohn Harrison ) 815b4100ccSJohn Harrison self.assertEqual(len(stackFrames), 3, "expected 3 frames with levels=3") 825b4100ccSJohn Harrison self.assertGreaterEqual( 835b4100ccSJohn Harrison totalFrames, i + 3, "total frames should include a pagination offset" 845b4100ccSJohn Harrison ) 855b4100ccSJohn Harrison self.assertEqual(stackFrames[1], frame) 865b4100ccSJohn Harrison 875b4100ccSJohn Harrison # Ensure requesting startFrame+levels at the beginning of a thread backtraces works as expected. 885b4100ccSJohn Harrison stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount( 895b4100ccSJohn Harrison threadId=events[0]["body"]["threadId"], startFrame=i, levels=3 905b4100ccSJohn Harrison ) 915b4100ccSJohn Harrison self.assertEqual(len(stackFrames), 3, "expected 3 frames with levels=3") 925b4100ccSJohn Harrison self.assertGreaterEqual( 935b4100ccSJohn Harrison totalFrames, i + 3, "total frames should include a pagination offset" 945b4100ccSJohn Harrison ) 955b4100ccSJohn Harrison self.assertEqual(stackFrames[0], frame) 965b4100ccSJohn Harrison 975b4100ccSJohn Harrison # Ensure requests with startFrame+levels that end precisely on the last frame includes the totalFrames pagination offset. 985b4100ccSJohn Harrison stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount( 995b4100ccSJohn Harrison threadId=events[0]["body"]["threadId"], startFrame=i - 1, levels=1 1005b4100ccSJohn Harrison ) 1015b4100ccSJohn Harrison self.assertEqual(len(stackFrames), 1, "expected 1 frames with levels=1") 1025b4100ccSJohn Harrison self.assertGreaterEqual( 1035b4100ccSJohn Harrison totalFrames, i, "total frames should include a pagination offset" 1045b4100ccSJohn Harrison ) 105