126 lines · python
1"""2Test lldb-dap stackTrace request with an extended backtrace thread.3"""4 5import os6 7import lldbdap_testcase8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10from lldbsuite.test.lldbplatformutil import *11 12 13class TestDAP_extendedStackTrace(lldbdap_testcase.DAPTestCaseBase):14 def build_and_run(self, displayExtendedBacktrace=True):15 backtrace_recording_lib = findBacktraceRecordingDylib()16 if not backtrace_recording_lib:17 self.skipTest(18 "Skipped because libBacktraceRecording.dylib was present on the system."19 )20 21 if not os.path.isfile("/usr/lib/system/introspection/libdispatch.dylib"):22 self.skipTest(23 "Skipped because introspection libdispatch dylib is not present."24 )25 26 program = self.getBuildArtifact("a.out")27 28 self.build_and_launch(29 program,30 env=[31 "DYLD_LIBRARY_PATH=/usr/lib/system/introspection",32 "DYLD_INSERT_LIBRARIES=" + backtrace_recording_lib,33 ],34 displayExtendedBacktrace=displayExtendedBacktrace,35 )36 source = "main.m"37 breakpoint = line_number(source, "breakpoint 1")38 lines = [breakpoint]39 40 breakpoint_ids = self.set_source_breakpoints(source, lines)41 self.assertEqual(42 len(breakpoint_ids), len(lines), "expect correct number of breakpoints"43 )44 45 @skipUnlessDarwin46 def test_stackTrace(self):47 """48 Tests the 'stackTrace' packet on a thread with an extended backtrace.49 """50 self.build_and_run()51 events = self.continue_to_next_stop()52 53 stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount(54 threadId=events[0]["body"]["threadId"]55 )56 self.assertGreaterEqual(len(stackFrames), 3, "expect >= 3 frames")57 self.assertEqual(len(stackFrames), totalFrames)58 self.assertEqual(stackFrames[0]["name"], "one")59 self.assertEqual(stackFrames[1]["name"], "two")60 self.assertEqual(stackFrames[2]["name"], "three")61 62 stackLabels = [63 (i, frame)64 for i, frame in enumerate(stackFrames)65 if frame.get("presentationHint", "") == "label"66 ]67 self.assertEqual(len(stackLabels), 2, "expected two label stack frames")68 self.assertRegex(69 stackLabels[0][1]["name"],70 r"Enqueued from com.apple.root.default-qos \(Thread \d\)",71 )72 self.assertRegex(73 stackLabels[1][1]["name"],74 r"Enqueued from com.apple.main-thread \(Thread \d\)",75 )76 77 for i, frame in stackLabels:78 # Ensure requesting startFrame+levels across thread backtraces works as expected.79 stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount(80 threadId=events[0]["body"]["threadId"], startFrame=i - 1, levels=381 )82 self.assertEqual(len(stackFrames), 3, "expected 3 frames with levels=3")83 self.assertGreaterEqual(84 totalFrames, i + 3, "total frames should include a pagination offset"85 )86 self.assertEqual(stackFrames[1], frame)87 88 # Ensure requesting startFrame+levels at the beginning of a thread backtraces works as expected.89 stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount(90 threadId=events[0]["body"]["threadId"], startFrame=i, levels=391 )92 self.assertEqual(len(stackFrames), 3, "expected 3 frames with levels=3")93 self.assertGreaterEqual(94 totalFrames, i + 3, "total frames should include a pagination offset"95 )96 self.assertEqual(stackFrames[0], frame)97 98 # Ensure requests with startFrame+levels that end precisely on the last frame includes the totalFrames pagination offset.99 stackFrames, totalFrames = self.get_stackFrames_and_totalFramesCount(100 threadId=events[0]["body"]["threadId"], startFrame=i - 1, levels=1101 )102 self.assertEqual(len(stackFrames), 1, "expected 1 frames with levels=1")103 self.assertGreaterEqual(104 totalFrames, i, "total frames should include a pagination offset"105 )106 107 @skipUnlessDarwin108 def test_stackTraceWithFormat(self):109 """110 Tests the 'stackTrace' packet on a thread with an extended backtrace using stack trace formats.111 """112 self.build_and_run(displayExtendedBacktrace=False)113 events = self.continue_to_next_stop()114 115 stackFrames, _ = self.get_stackFrames_and_totalFramesCount(116 threadId=events[0]["body"]["threadId"], format={"includeAll": True}117 )118 119 stackLabels = [120 (i, frame)121 for i, frame in enumerate(stackFrames)122 if frame.get("presentationHint", "") == "label"123 ]124 125 self.assertEqual(len(stackLabels), 2, "expected two label stack frames")126