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