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