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