xref: /llvm-project/lldb/test/API/functionalities/bt-interrupt/TestInterruptBacktrace.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1e19387e6SJim Ingham"""
2e19387e6SJim InghamEnsure that when the interrupt is raised we still make frame 0.
3e19387e6SJim Inghamand make sure "GetNumFrames" isn't interrupted.
4e19387e6SJim Ingham"""
5e19387e6SJim Ingham
6e19387e6SJim Inghamimport lldb
7e19387e6SJim Inghamimport lldbsuite.test.lldbutil as lldbutil
8e19387e6SJim Inghamfrom lldbsuite.test.lldbtest import *
9a7c7c61aSMuhammad Omair Javaidfrom lldbsuite.test.decorators import *
10e19387e6SJim Ingham
11e19387e6SJim Ingham
12*2238dcc3SJonas Devlieghereclass TestInterruptingBacktrace(TestBase):
13e19387e6SJim Ingham    NO_DEBUG_INFO_TESTCASE = True
14e19387e6SJim Ingham
155dfec676SMuhammad Omair Javaid    @skipIf(oslist=["linux"], archs=["arm"])
16e19387e6SJim Ingham    def test_backtrace_interrupt(self):
17e19387e6SJim Ingham        """Use RequestInterrupt followed by stack operations
18e19387e6SJim Ingham        to ensure correct interrupt behavior for stacks."""
19e19387e6SJim Ingham        self.build()
20e19387e6SJim Ingham        self.main_source_file = lldb.SBFileSpec("main.c")
21e19387e6SJim Ingham        self.bt_interrupt_test()
22e19387e6SJim Ingham
23e19387e6SJim Ingham    def bt_interrupt_test(self):
24*2238dcc3SJonas Devlieghere        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
25*2238dcc3SJonas Devlieghere            self, "Set a breakpoint here", self.main_source_file
26*2238dcc3SJonas Devlieghere        )
27e19387e6SJim Ingham
28e19387e6SJim Ingham        # Now continue, and when we stop we will have crashed.
29e19387e6SJim Ingham        process.Continue()
30e19387e6SJim Ingham        self.dbg.RequestInterrupt()
31e19387e6SJim Ingham
32e19387e6SJim Ingham        # Be sure to turn this off again:
33e19387e6SJim Ingham        def cleanup():
34e19387e6SJim Ingham            if self.dbg.InterruptRequested():
35e19387e6SJim Ingham                self.dbg.CancelInterruptRequest()
36*2238dcc3SJonas Devlieghere
37e19387e6SJim Ingham        self.addTearDownHook(cleanup)
38e19387e6SJim Ingham
39e19387e6SJim Ingham        frame_0 = thread.GetFrameAtIndex(0)
40e19387e6SJim Ingham        self.assertTrue(frame_0.IsValid(), "Got a good 0th frame")
41e19387e6SJim Ingham        # The interrupt flag is up already, so any attempt to backtrace
42e19387e6SJim Ingham        # should be cut short:
43e19387e6SJim Ingham        frame_1 = thread.GetFrameAtIndex(1)
44e19387e6SJim Ingham        self.assertFalse(frame_1.IsValid(), "Prevented from getting more frames")
45e19387e6SJim Ingham        # Since GetNumFrames is a contract, we don't interrupt it:
46e19387e6SJim Ingham        num_frames = thread.GetNumFrames()
47e19387e6SJim Ingham        print(f"Number of frames: {num_frames}")
48e19387e6SJim Ingham        self.assertGreater(num_frames, 1, "Got many frames")
49e19387e6SJim Ingham
50e19387e6SJim Ingham        self.dbg.CancelInterruptRequest()
51