1""" 2Use lldb Python SBValue.WatchPointee() API to create a watchpoint for write of '*g_char_ptr'. 3""" 4 5import lldb 6from lldbsuite.test.decorators import * 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test import lldbutil 9 10 11class SetWatchlocationAPITestCase(TestBase): 12 NO_DEBUG_INFO_TESTCASE = True 13 14 def setUp(self): 15 # Call super's setUp(). 16 TestBase.setUp(self) 17 # Our simple source filename. 18 self.source = "main.cpp" 19 # Find the line number to break inside main(). 20 self.line = line_number(self.source, "// Set break point at this line.") 21 # This is for verifying that watch location works. 22 self.violating_func = "do_bad_thing_with_location" 23 24 @skipIfWindows # This test is flaky on Windows 25 def test_watch_location(self): 26 """Exercise SBValue.WatchPointee() API to set a watchpoint.""" 27 self.build() 28 exe = self.getBuildArtifact("a.out") 29 30 # Create a target by the debugger. 31 target = self.dbg.CreateTarget(exe) 32 self.assertTrue(target, VALID_TARGET) 33 34 # Now create a breakpoint on main.c. 35 breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 36 self.assertTrue( 37 breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 38 ) 39 40 # Now launch the process, and do not stop at the entry point. 41 process = target.LaunchSimple(None, None, self.get_process_working_directory()) 42 43 # We should be stopped due to the breakpoint. Get frame #0. 44 process = target.GetProcess() 45 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 46 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 47 frame0 = thread.GetFrameAtIndex(0) 48 49 value = frame0.FindValue("g_char_ptr", lldb.eValueTypeVariableGlobal) 50 pointee = value.CreateValueFromAddress( 51 "pointee", value.GetValueAsUnsigned(0), value.GetType().GetPointeeType() 52 ) 53 # Watch for write to *g_char_ptr. 54 error = lldb.SBError() 55 watchpoint = value.WatchPointee(True, False, True, error) 56 self.assertTrue( 57 value and watchpoint, "Successfully found the pointer and set a watchpoint" 58 ) 59 self.DebugSBValue(value) 60 self.DebugSBValue(pointee) 61 62 # Check some API calls return expected values 63 self.assertEqual( 64 watchpoint.GetWatchValueKind(), lldb.eWatchPointValueKindExpression 65 ) 66 # FIXME: The spec should probably be 'g_char_ptr' 67 self.assertEqual(watchpoint.GetWatchSpec(), None) 68 self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), "char") 69 self.assertFalse(watchpoint.IsWatchingReads()) 70 self.assertTrue(watchpoint.IsWatchingWrites()) 71 72 # Hide stdout if not running with '-t' option. 73 if not self.TraceOn(): 74 self.HideStdout() 75 76 print(watchpoint) 77 78 # Continue. Expect the program to stop due to the variable being 79 # written to. 80 process.Continue() 81 82 if self.TraceOn(): 83 lldbutil.print_stacktraces(process) 84 85 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) 86 self.assertTrue(thread, "The thread stopped due to watchpoint") 87 self.DebugSBValue(value) 88 self.DebugSBValue(pointee) 89 90 self.expect( 91 lldbutil.print_stacktrace(thread, string_buffer=True), 92 exe=False, 93 substrs=[self.violating_func], 94 ) 95 96 # This finishes our test. 97