1""" 2Test embedded breakpoints, like `asm int 3;` in x86 or or `__debugbreak` on Windows. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class DebugBreakTestCase(TestBase): 13 @skipIf(archs=no_match(["i386", "i686", "x86_64"])) 14 @no_debug_info_test 15 def test_asm_int_3(self): 16 """Test that intrinsics like `__debugbreak();` and `asm {"int3"}` are treated like breakpoints.""" 17 self.build() 18 exe = self.getBuildArtifact("a.out") 19 20 # Run the program. 21 target = self.dbg.CreateTarget(exe) 22 process = target.LaunchSimple(None, None, self.get_process_working_directory()) 23 24 # We've hit the first stop, so grab the frame. 25 self.assertState(process.GetState(), lldb.eStateStopped) 26 stop_reason = ( 27 lldb.eStopReasonException 28 if ( 29 lldbplatformutil.getPlatform() == "windows" 30 or lldbplatformutil.getPlatform() == "macosx" 31 ) 32 else lldb.eStopReasonSignal 33 ) 34 thread = lldbutil.get_stopped_thread(process, stop_reason) 35 self.assertIsNotNone( 36 thread, "Unable to find thread stopped at the __debugbreak()" 37 ) 38 frame = thread.GetFrameAtIndex(0) 39 40 # We should be in function 'bar'. 41 self.assertTrue(frame.IsValid()) 42 function_name = frame.GetFunctionName() 43 self.assertIn( 44 "bar", function_name, "Unexpected function name {}".format(function_name) 45 ) 46 47 # We should be able to evaluate the parameter foo. 48 value = frame.EvaluateExpression("*foo") 49 self.assertEqual(value.GetValueAsSigned(), 42) 50 51 # The counter should be 1 at the first stop and increase by 2 for each 52 # subsequent stop. 53 counter = 1 54 while counter < 20: 55 value = frame.EvaluateExpression("count") 56 self.assertEqual(value.GetValueAsSigned(), counter) 57 counter += 2 58 process.Continue() 59 60 # The inferior should exit after the last iteration. 61 self.assertState(process.GetState(), lldb.eStateExited) 62