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