150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen""" 250e0534f2edd82964a997cde7a79c540e38e76baJohnny ChenUse lldb Python SBtarget.WatchAddress() API to create a watchpoint for write of '*g_char_ptr'. 350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen""" 450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport os, time 650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport re 750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport unittest2 850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenimport lldb, lldbutil 950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenfrom lldbtest import * 1050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 1150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenclass TargetWatchAddressAPITestCase(TestBase): 1250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 1350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen mydir = os.path.join("python_api", "watchpoint", "watchlocation") 1450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 1550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen def setUp(self): 1650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Call super's setUp(). 1750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen TestBase.setUp(self) 1850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Our simple source filename. 1950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.source = 'main.cpp' 2050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Find the line number to break inside main(). 2150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.line = line_number(self.source, '// Set break point at this line.') 2250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # This is for verifying that watch location works. 2350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.violating_func = "do_bad_thing_with_location"; 2450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 2550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 2650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen @python_api_test 2721b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen @dsym_test 2850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen def test_watch_address_with_dsym(self): 2950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen """Exercise SBTarget.WatchAddress() API to set a watchpoint.""" 3050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.buildDsym() 3150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.do_set_watchaddress() 3250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 333bf526ac0f51dda6f63be3421cd7de68720dd656Ed Maste @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD 344f2353a3c264d45500293f38e21b623bf59b6117Matt Kopec @skipIfLinux # llvm.org/pr14323 - skip due to incomplete multi-threaded debug support 3550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen @python_api_test 3621b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen @dwarf_test 3715bb3cf9a0ba3778623e010d9f1fe9d1d67386c4Johnny Chen def test_watch_address_with_dwarf(self): 3850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen """Exercise SBTarget.WatchAddress() API to set a watchpoint.""" 3950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.buildDwarf() 4050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.do_set_watchaddress() 4150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 423f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 433f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen @python_api_test 443f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen @dsym_test 453f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen def test_watch_address_with_invalid_watch_size_with_dsym(self): 463f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" 473f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.buildDsym() 483f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.do_set_watchaddress_with_invalid_watch_size() 493f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 503f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen @python_api_test 513f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen @dwarf_test 523f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen def test_watch_address_with_invalid_watch_size_with_dwarf(self): 533f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" 543f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.buildDwarf() 553f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.do_set_watchaddress_with_invalid_watch_size() 563f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 5750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen def do_set_watchaddress(self): 5850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen """Use SBTarget.WatchAddress() to set a watchpoint and verify that the program stops later due to the watchpoint.""" 5950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen exe = os.path.join(os.getcwd(), "a.out") 6050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 6150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Create a target by the debugger. 6250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen target = self.dbg.CreateTarget(exe) 6350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.assertTrue(target, VALID_TARGET) 6450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 6550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Now create a breakpoint on main.c. 6650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 6750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.assertTrue(breakpoint and 6850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen breakpoint.GetNumLocations() == 1, 6950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen VALID_BREAKPOINT) 7050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 7150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Now launch the process, and do not stop at the entry point. 7250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen process = target.LaunchSimple(None, None, os.getcwd()) 7350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 7450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # We should be stopped due to the breakpoint. Get frame #0. 7550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen process = target.GetProcess() 7650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.assertTrue(process.GetState() == lldb.eStateStopped, 7750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen PROCESS_STOPPED) 7850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 7950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen frame0 = thread.GetFrameAtIndex(0) 8050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 8150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen value = frame0.FindValue('g_char_ptr', 8250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen lldb.eValueTypeVariableGlobal) 8350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen pointee = value.CreateValueFromAddress("pointee", 8450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen value.GetValueAsUnsigned(0), 8550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen value.GetType().GetPointeeType()) 8650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Watch for write to *g_char_ptr. 873f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen error = lldb.SBError(); 883f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True, error) 8950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.assertTrue(value and watchpoint, 9050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen "Successfully found the pointer and set a watchpoint") 9150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.DebugSBValue(value) 9250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.DebugSBValue(pointee) 9350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 9450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Hide stdout if not running with '-t' option. 9550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen if not self.TraceOn(): 9650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.HideStdout() 9750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 9850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen print watchpoint 9950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 10050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # Continue. Expect the program to stop due to the variable being written to. 10150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen process.Continue() 10250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 10350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen if (self.TraceOn()): 10450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen lldbutil.print_stacktraces(process) 10550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 10650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) 10750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.assertTrue(thread, "The thread stopped due to watchpoint") 10850e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.DebugSBValue(value) 10950e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.DebugSBValue(pointee) 11050e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 11150e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen self.expect(lldbutil.print_stacktrace(thread, string_buffer=True), exe=False, 11250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen substrs = [self.violating_func]) 11350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 11450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen # This finishes our test. 11550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 1163f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen def do_set_watchaddress_with_invalid_watch_size(self): 1173f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen """Use SBTarget.WatchAddress() to set a watchpoint with invalid watch_size and verify we get a meaningful error message.""" 1183f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen exe = os.path.join(os.getcwd(), "a.out") 1193f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 1203f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen # Create a target by the debugger. 1213f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen target = self.dbg.CreateTarget(exe) 1223f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.assertTrue(target, VALID_TARGET) 1233f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 1243f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen # Now create a breakpoint on main.c. 1253f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 1263f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.assertTrue(breakpoint and 1273f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen breakpoint.GetNumLocations() == 1, 1283f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen VALID_BREAKPOINT) 1293f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 1303f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen # Now launch the process, and do not stop at the entry point. 1313f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen process = target.LaunchSimple(None, None, os.getcwd()) 1323f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 1333f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen # We should be stopped due to the breakpoint. Get frame #0. 1343f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen process = target.GetProcess() 1353f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.assertTrue(process.GetState() == lldb.eStateStopped, 1363f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen PROCESS_STOPPED) 1373f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 1383f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen frame0 = thread.GetFrameAtIndex(0) 1393f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 1403f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen value = frame0.FindValue('g_char_ptr', 1413f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen lldb.eValueTypeVariableGlobal) 1423f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen pointee = value.CreateValueFromAddress("pointee", 1433f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen value.GetValueAsUnsigned(0), 1443f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen value.GetType().GetPointeeType()) 1453f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen # Watch for write to *g_char_ptr. 1463f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen error = lldb.SBError(); 1473f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 365, False, True, error) 1483f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.assertFalse(watchpoint) 1493f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen self.expect(error.GetCString(), exe=False, 1503f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen substrs = ['watch size of %d is not supported' % 365]) 1513f883496e92fce5011f6bf585af3ac6d1cddb64fJohnny Chen 15250e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen 15350e0534f2edd82964a997cde7a79c540e38e76baJohnny Chenif __name__ == '__main__': 15450e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen import atexit 15550e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen lldb.SBDebugger.Initialize() 15650e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen atexit.register(lambda: lldb.SBDebugger.Terminate()) 15750e0534f2edd82964a997cde7a79c540e38e76baJohnny Chen unittest2.main() 158