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 *
10
11class TestLinux64LaunchingViaDynamicLoader(TestBase):
12
13    @skipIf(oslist=no_match(['linux']))
14    @no_debug_info_test
15    @skipIf(oslist=["linux"], archs=["arm"])
16    def test(self):
17        self.build()
18
19        # Extracts path of the interpreter.
20        spec = lldb.SBModuleSpec()
21        spec.SetFileSpec(lldb.SBFileSpec(self.getBuildArtifact("a.out")))
22        interp_section = lldb.SBModule(spec).FindSection(".interp")
23        if not interp_section:
24          return
25        section_data = interp_section.GetSectionData()
26        error = lldb.SBError()
27        exe = section_data.GetString(error,0)
28        if error.Fail():
29          return
30
31        target = self.dbg.CreateTarget(exe)
32        self.assertTrue(target, VALID_TARGET)
33
34        # Set breakpoints both on shared library function as well as on
35        # main. Both of them will be pending breakpoints.
36        breakpoint_main = target.BreakpointCreateBySourceRegex("// Break here", lldb.SBFileSpec("main.cpp"))
37        breakpoint_shared_library = target.BreakpointCreateBySourceRegex("get_signal_crash", lldb.SBFileSpec("signal_file.cpp"))
38        launch_info = lldb.SBLaunchInfo([ "--library-path", self.get_process_working_directory(), self.getBuildArtifact("a.out")])
39        launch_info.SetWorkingDirectory(self.get_process_working_directory())
40        error = lldb.SBError()
41        process = target.Launch(launch_info, error)
42        self.assertSuccess(error)
43
44        # Stopped on main here.
45        self.assertState(process.GetState(), lldb.eStateStopped)
46        thread = process.GetSelectedThread()
47        self.assertIn("main", thread.GetFrameAtIndex(0).GetDisplayFunctionName())
48        process.Continue()
49
50        # Stopped on get_signal_crash function here.
51        self.assertState(process.GetState(), lldb.eStateStopped)
52        self.assertIn("get_signal_crash", thread.GetFrameAtIndex(0).GetDisplayFunctionName())
53        process.Continue()
54
55        # Stopped because of generated signal.
56        self.assertState(process.GetState(), lldb.eStateStopped)
57        self.assertIn("raise", lldbutil.get_function_names(thread))
58