xref: /llvm-project/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py (revision fa6377119c0624773cb698935692d46843e9f6ec)
1"""
2Test lldb-dap setBreakpoints request
3"""
4
5import dap_server
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9import lldbdap_testcase
10import re
11
12
13class TestDAP_module(lldbdap_testcase.DAPTestCaseBase):
14    def run_test(self, symbol_basename, expect_debug_info_size):
15        program_basename = "a.out.stripped"
16        program = self.getBuildArtifact(program_basename)
17        self.build_and_launch(program)
18        functions = ["foo"]
19        breakpoint_ids = self.set_function_breakpoints(functions)
20        self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint")
21        self.continue_to_breakpoints(breakpoint_ids)
22        active_modules = self.dap_server.get_modules()
23        program_module = active_modules[program_basename]
24        self.assertIn(
25            program_basename,
26            active_modules,
27            "%s module is in active modules" % (program_basename),
28        )
29        self.assertIn("name", program_module, "make sure name is in module")
30        self.assertEqual(program_basename, program_module["name"])
31        self.assertIn("path", program_module, "make sure path is in module")
32        self.assertEqual(program, program_module["path"])
33        self.assertNotIn(
34            "symbolFilePath",
35            program_module,
36            "Make sure a.out.stripped has no debug info",
37        )
38        symbols_path = self.getBuildArtifact(symbol_basename)
39        self.dap_server.request_evaluate(
40            "`%s" % ('target symbols add -s "%s" "%s"' % (program, symbols_path)),
41            context="repl",
42        )
43
44        def checkSymbolsLoadedWithSize():
45            active_modules = self.dap_server.get_modules()
46            program_module = active_modules[program_basename]
47            self.assertIn("symbolFilePath", program_module)
48            self.assertIn(symbols_path, program_module["symbolFilePath"])
49            symbol_regex = re.compile(r"[0-9]+(\.[0-9]*)?[KMG]?B")
50            return symbol_regex.match(program_module["symbolStatus"])
51
52        if expect_debug_info_size:
53            self.waitUntil(checkSymbolsLoadedWithSize)
54        active_modules = self.dap_server.get_modules()
55        program_module = active_modules[program_basename]
56        self.assertEqual(program_basename, program_module["name"])
57        self.assertEqual(program, program_module["path"])
58        self.assertIn("addressRange", program_module)
59
60    @skipIfWindows
61    def test_modules(self):
62        """
63        Mac or linux.
64
65        On mac, if we load a.out as our symbol file, we will use DWARF with .o files and we will
66        have debug symbols, but we won't see any debug info size because all of the DWARF
67        sections are in .o files.
68
69        On other platforms, we expect a.out to have debug info, so we will expect a size.
70        """
71        return self.run_test(
72            "a.out", expect_debug_info_size=platform.system() != "Darwin"
73        )
74
75    @skipUnlessDarwin
76    def test_modules_dsym(self):
77        """
78        Darwin only test with dSYM file.
79
80        On mac, if we load a.out.dSYM as our symbol file, we will have debug symbols and we
81        will have DWARF sections added to the module, so we will expect a size.
82        """
83        return self.run_test("a.out.dSYM", expect_debug_info_size=True)
84
85    @skipIfWindows
86    def test_compile_units(self):
87        program = self.getBuildArtifact("a.out")
88        self.build_and_launch(program)
89        source = "main.cpp"
90        main_source_path = self.getSourcePath(source)
91        breakpoint1_line = line_number(source, "// breakpoint 1")
92        lines = [breakpoint1_line]
93        breakpoint_ids = self.set_source_breakpoints(source, lines)
94        self.continue_to_breakpoints(breakpoint_ids)
95        moduleId = self.dap_server.get_modules()["a.out"]["id"]
96        response = self.dap_server.request_compileUnits(moduleId)
97        self.assertTrue(response["body"])
98        cu_paths = [cu["compileUnitPath"] for cu in response["body"]["compileUnits"]]
99        self.assertIn(main_source_path, cu_paths, "Real path to main.cpp matches")
100