xref: /llvm-project/lldb/test/API/functionalities/unwind/sigtramp/TestSigtrampUnwind.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""
2Test that we can backtrace correctly with 'sigtramp' functions on the stack
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11class SigtrampUnwind(TestBase):
12    # On different platforms the "_sigtramp" and "__kill" frames are likely to be different.
13    # This test could probably be adapted to run on linux/*bsd easily enough.
14    @skipUnlessDarwin
15    @expectedFailureAll(
16        archs=["arm64"], bugnumber="<rdar://problem/34006863>"
17    )  # lldb skips 1 frame on arm64 above _sigtramp
18    def test(self):
19        """Test that we can backtrace correctly with _sigtramp on the stack"""
20        self.build()
21        self.setTearDownCleanup()
22
23        exe = self.getBuildArtifact("a.out")
24        target = self.dbg.CreateTarget(exe)
25        self.assertTrue(target, VALID_TARGET)
26
27        lldbutil.run_break_set_by_file_and_line(
28            self,
29            "main.c",
30            line_number("main.c", "// Set breakpoint here"),
31            num_expected_locations=1,
32        )
33
34        process = target.LaunchSimple(None, None, self.get_process_working_directory())
35
36        if not process:
37            self.fail("SBTarget.Launch() failed")
38
39        if process.GetState() != lldb.eStateStopped:
40            self.fail(
41                "Process should be in the 'stopped' state, "
42                "instead the actual state is: '%s'"
43                % lldbutil.state_type_to_str(process.GetState())
44            )
45
46        self.expect(
47            "pro handle  -n false -p true -s false SIGUSR1",
48            "Have lldb pass SIGUSR1 signals",
49            substrs=["SIGUSR1", "true", "false", "false"],
50        )
51
52        lldbutil.run_break_set_by_symbol(
53            self, "handler", num_expected_locations=1, module_name="a.out"
54        )
55
56        self.runCmd("continue")
57
58        thread = process.GetThreadAtIndex(0)
59
60        found_handler = False
61        found_sigtramp = False
62        found_kill = False
63        found_main = False
64
65        for f in thread.frames:
66            if f.GetFunctionName() == "handler":
67                found_handler = True
68            if f.GetFunctionName() == "_sigtramp":
69                found_sigtramp = True
70            if f.GetFunctionName() == "__kill":
71                found_kill = True
72            if f.GetFunctionName() == "main":
73                found_main = True
74
75        if self.TraceOn():
76            print("Backtrace once we're stopped:")
77            for f in thread.frames:
78                print("  %d %s" % (f.GetFrameID(), f.GetFunctionName()))
79
80        if not found_handler:
81            self.fail("Unable to find handler() in backtrace.")
82
83        if not found_sigtramp:
84            self.fail("Unable to find _sigtramp() in backtrace.")
85
86        if not found_kill:
87            self.fail("Unable to find kill() in backtrace.")
88
89        if not found_main:
90            self.fail("Unable to find main() in backtrace.")
91