xref: /llvm-project/lldb/test/API/functionalities/longjmp/TestLongjmp.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""
2Test the use of setjmp/longjmp for non-local goto operations in a single-threaded inferior.
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class LongjmpTestCase(TestBase):
13    @skipIfDarwin  # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
14    @expectedFailureAll(oslist=["freebsd", "linux"], bugnumber="llvm.org/pr20231")
15    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
16    @expectedFlakeyNetBSD
17    def test_step_out(self):
18        """Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-out."""
19        self.build()
20        self.step_out()
21
22    @skipIfDarwin  # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
23    @expectedFailureAll(oslist=["freebsd", "linux"], bugnumber="llvm.org/pr20231")
24    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
25    @skipIfNetBSD
26    def test_step_over(self):
27        """Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-over a longjmp."""
28        self.build()
29        self.step_over()
30
31    @skipIfDarwin  # llvm.org/pr16769: LLDB on Mac OS X dies in function ReadRegisterBytes in GDBRemoteRegisterContext.cpp
32    @expectedFailureAll(oslist=["freebsd", "linux"], bugnumber="llvm.org/pr20231")
33    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
34    @expectedFlakeyNetBSD
35    def test_step_back_out(self):
36        """Test stepping when the inferior calls setjmp/longjmp, in particular, thread step-out after thread step-in."""
37        self.build()
38        self.step_back_out()
39
40    def start_test(self, symbol):
41        exe = self.getBuildArtifact("a.out")
42
43        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
44
45        # Break in main().
46        lldbutil.run_break_set_by_symbol(self, symbol, num_expected_locations=-1)
47
48        self.runCmd("run", RUN_SUCCEEDED)
49
50        # The stop reason of the thread should be breakpoint.
51        self.expect(
52            "thread list",
53            STOPPED_DUE_TO_BREAKPOINT,
54            substrs=["stopped", "stop reason = breakpoint"],
55        )
56
57    def check_status(self):
58        # Note: Depending on the generated mapping of DWARF to assembly,
59        # the process may have stopped or exited.
60        self.expect(
61            "process status",
62            PROCESS_STOPPED,
63            patterns=["Process .* exited with status = 0"],
64        )
65
66    def step_out(self):
67        self.start_test("do_jump")
68        self.runCmd("thread step-out", RUN_SUCCEEDED)
69        self.check_status()
70
71    def step_over(self):
72        self.start_test("do_jump")
73        self.runCmd("thread step-over", RUN_SUCCEEDED)
74        self.runCmd("thread step-over", RUN_SUCCEEDED)
75        self.check_status()
76
77    def step_back_out(self):
78        self.start_test("main")
79
80        self.runCmd("thread step-over", RUN_SUCCEEDED)
81        self.runCmd("thread step-in", RUN_SUCCEEDED)
82        self.runCmd("thread step-out", RUN_SUCCEEDED)
83        self.check_status()
84