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