xref: /llvm-project/lldb/test/API/functionalities/dyld-launch-linux/TestDyldLaunchLinux.py (revision ac42f7689d741feda2badc438101e7952db048f3)
1"""
2Test that LLDB can launch a linux executable through the dynamic loader and still hit a breakpoint.
3"""
4
5import lldb
6import os
7
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class TestLinux64LaunchingViaDynamicLoader(TestBase):
14    @skipIf(oslist=no_match(["linux"]))
15    @no_debug_info_test
16    @skipIf(oslist=["linux"], archs=["arm"])
17    def test(self):
18        self.build()
19
20        # Extracts path of the interpreter.
21        spec = lldb.SBModuleSpec()
22        spec.SetFileSpec(lldb.SBFileSpec(self.getBuildArtifact("a.out")))
23        interp_section = lldb.SBModule(spec).FindSection(".interp")
24        if not interp_section:
25            return
26        section_data = interp_section.GetSectionData()
27        error = lldb.SBError()
28        exe = section_data.GetString(error, 0)
29        if error.Fail():
30            return
31
32        target = self.dbg.CreateTarget(exe)
33        self.assertTrue(target, VALID_TARGET)
34
35        # Set breakpoints both on shared library function as well as on
36        # main. Both of them will be pending breakpoints.
37        breakpoint_main = target.BreakpointCreateBySourceRegex(
38            "// Break here", lldb.SBFileSpec("main.cpp")
39        )
40        breakpoint_shared_library = target.BreakpointCreateBySourceRegex(
41            "get_signal_crash", lldb.SBFileSpec("signal_file.cpp")
42        )
43        inferior_exe_path = lldbutil.install_to_target(
44            self, self.getBuildArtifact("a.out")
45        )
46        lldbutil.install_to_target(self, self.getBuildArtifact("libsignal_file.so"))
47
48        launch_info = lldb.SBLaunchInfo(
49            [
50                "--library-path",
51                self.get_process_working_directory(),
52                inferior_exe_path,
53            ]
54        )
55        launch_info.SetWorkingDirectory(self.get_process_working_directory())
56        error = lldb.SBError()
57        process = target.Launch(launch_info, error)
58        self.assertSuccess(error)
59
60        # Stopped on main here.
61        self.assertState(process.GetState(), lldb.eStateStopped)
62        thread = process.GetSelectedThread()
63        self.assertIn("main", thread.GetFrameAtIndex(0).GetDisplayFunctionName())
64        process.Continue()
65
66        # Stopped on get_signal_crash function here.
67        self.assertState(process.GetState(), lldb.eStateStopped)
68        self.assertIn(
69            "get_signal_crash", thread.GetFrameAtIndex(0).GetDisplayFunctionName()
70        )
71        process.Continue()
72
73        # Stopped because of generated signal.
74        self.assertState(process.GetState(), lldb.eStateStopped)
75        self.assertIn("raise", lldbutil.get_function_names(thread))
76