172 lines
5.7 KiB
Python
172 lines
5.7 KiB
Python
"""
|
|
Test lldb-dap stack trace when some of the source paths are missing
|
|
"""
|
|
|
|
from lldbsuite.test.lldbtest import line_number
|
|
import lldbdap_testcase
|
|
from contextlib import contextmanager
|
|
import os
|
|
|
|
|
|
OTHER_C_SOURCE_CODE = """
|
|
int no_source_func(int n) {
|
|
return n + 1; // Break here
|
|
}
|
|
"""
|
|
|
|
|
|
@contextmanager
|
|
def delete_file_on_exit(path):
|
|
try:
|
|
yield path
|
|
finally:
|
|
if os.path.exists(path):
|
|
os.remove(path)
|
|
|
|
|
|
class TestDAP_stackTraceMissingSourcePath(lldbdap_testcase.DAPTestCaseBase):
|
|
def build_and_run_until_breakpoint(self):
|
|
"""
|
|
Build the program and run until the breakpoint is hit, and return the stack frames.
|
|
"""
|
|
other_source_file = "other.c"
|
|
with delete_file_on_exit(other_source_file):
|
|
with open(other_source_file, "w") as f:
|
|
f.write(OTHER_C_SOURCE_CODE)
|
|
|
|
breakpoint_line = line_number(other_source_file, "// Break here")
|
|
|
|
program = self.getBuildArtifact("a.out")
|
|
self.build_and_launch(program, commandEscapePrefix="")
|
|
|
|
breakpoint_ids = self.set_source_breakpoints(
|
|
other_source_file, [breakpoint_line]
|
|
)
|
|
self.assertEqual(
|
|
len(breakpoint_ids), 1, "expect correct number of breakpoints"
|
|
)
|
|
|
|
self.continue_to_breakpoints(breakpoint_ids)
|
|
|
|
frames = self.get_stackFrames()
|
|
self.assertLessEqual(2, len(frames), "expect at least 2 frames")
|
|
|
|
self.assertIn(
|
|
"path",
|
|
frames[0]["source"],
|
|
"Expect source path to always be in frame (other.c)",
|
|
)
|
|
self.assertIn(
|
|
"path",
|
|
frames[1]["source"],
|
|
"Expect source path in always be in frame (main.c)",
|
|
)
|
|
|
|
return frames
|
|
|
|
def verify_frames_source(
|
|
self, frames, main_frame_assembly: bool, other_frame_assembly: bool
|
|
):
|
|
self.assertLessEqual(2, len(frames), "expect at least 2 frames")
|
|
source_0 = frames[0].get("source")
|
|
source_1 = frames[1].get("source")
|
|
self.assertIsNotNone(source_0, "Expects a source object in frame 0")
|
|
self.assertIsNotNone(source_1, "Expects a source object in frame 1")
|
|
|
|
# it does not always have a path.
|
|
source_0_path: str = source_0.get("path", "")
|
|
source_1_path: str = source_1.get("path", "")
|
|
|
|
if other_frame_assembly:
|
|
self.assertFalse(
|
|
source_0_path.endswith("other.c"),
|
|
"Expect original source path to not be in unavailable source frame (other.c)",
|
|
)
|
|
self.assertIn(
|
|
"sourceReference",
|
|
source_0,
|
|
"Expect sourceReference to be in unavailable source frame (other.c)",
|
|
)
|
|
else:
|
|
self.assertTrue(
|
|
source_0_path.endswith("other.c"),
|
|
"Expect original source path to be in normal source frame (other.c)",
|
|
)
|
|
self.assertNotIn(
|
|
"sourceReference",
|
|
source_0,
|
|
"Expect sourceReference to not be in normal source frame (other.c)",
|
|
)
|
|
|
|
if main_frame_assembly:
|
|
self.assertFalse(
|
|
source_1_path.endswith("main.c"),
|
|
"Expect original source path to not be in unavailable source frame (main.c)",
|
|
)
|
|
self.assertIn(
|
|
"sourceReference",
|
|
source_1,
|
|
"Expect sourceReference to be in unavailable source frame (main.c)",
|
|
)
|
|
else:
|
|
self.assertTrue(
|
|
source_1_path.endswith("main.c"),
|
|
"Expect original source path to be in normal source frame (main.c)",
|
|
)
|
|
self.assertNotIn(
|
|
"sourceReference",
|
|
source_1,
|
|
"Expect sourceReference to not be in normal source code frame (main.c)",
|
|
)
|
|
|
|
def test_stopDisassemblyDisplay(self):
|
|
"""
|
|
Test that with with all stop-disassembly-display values you get correct assembly / no assembly source code.
|
|
"""
|
|
self.build_and_run_until_breakpoint()
|
|
frames = self.get_stackFrames()
|
|
self.assertLessEqual(2, len(frames), "expect at least 2 frames")
|
|
|
|
self.assertIn(
|
|
"path",
|
|
frames[0]["source"],
|
|
"Expect source path to always be in frame (other.c)",
|
|
)
|
|
self.assertIn(
|
|
"path",
|
|
frames[1]["source"],
|
|
"Expect source path in always be in frame (main.c)",
|
|
)
|
|
|
|
self.dap_server.request_evaluate(
|
|
"settings set stop-disassembly-display never", context="repl"
|
|
)
|
|
frames = self.get_stackFrames()
|
|
self.verify_frames_source(
|
|
frames, main_frame_assembly=False, other_frame_assembly=False
|
|
)
|
|
|
|
self.dap_server.request_evaluate(
|
|
"settings set stop-disassembly-display always", context="repl"
|
|
)
|
|
frames = self.get_stackFrames()
|
|
self.verify_frames_source(
|
|
frames, main_frame_assembly=True, other_frame_assembly=True
|
|
)
|
|
|
|
self.dap_server.request_evaluate(
|
|
"settings set stop-disassembly-display no-source", context="repl"
|
|
)
|
|
frames = self.get_stackFrames()
|
|
self.verify_frames_source(
|
|
frames, main_frame_assembly=False, other_frame_assembly=True
|
|
)
|
|
|
|
self.dap_server.request_evaluate(
|
|
"settings set stop-disassembly-display no-debuginfo", context="repl"
|
|
)
|
|
frames = self.get_stackFrames()
|
|
self.verify_frames_source(
|
|
frames, main_frame_assembly=False, other_frame_assembly=False
|
|
)
|