199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtUse lldb Python SBValue.WatchPointee() API to create a watchpoint for write of '*g_char_ptr'. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtimport lldb 699451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 799451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 899451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 999451b44SJordan Rupprecht 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprechtclass SetWatchlocationAPITestCase(TestBase): 1299451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprecht def setUp(self): 1599451b44SJordan Rupprecht # Call super's setUp(). 1699451b44SJordan Rupprecht TestBase.setUp(self) 1799451b44SJordan Rupprecht # Our simple source filename. 18*2238dcc3SJonas Devlieghere self.source = "main.cpp" 1999451b44SJordan Rupprecht # Find the line number to break inside main(). 20*2238dcc3SJonas Devlieghere self.line = line_number(self.source, "// Set break point at this line.") 2199451b44SJordan Rupprecht # This is for verifying that watch location works. 2299451b44SJordan Rupprecht self.violating_func = "do_bad_thing_with_location" 2399451b44SJordan Rupprecht 249b5cf726SStella Stamenova @skipIfWindows # This test is flaky on Windows 2599451b44SJordan Rupprecht def test_watch_location(self): 2699451b44SJordan Rupprecht """Exercise SBValue.WatchPointee() API to set a watchpoint.""" 2799451b44SJordan Rupprecht self.build() 2899451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 2999451b44SJordan Rupprecht 3099451b44SJordan Rupprecht # Create a target by the debugger. 3199451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 3299451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 3399451b44SJordan Rupprecht 3499451b44SJordan Rupprecht # Now create a breakpoint on main.c. 3599451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 36*2238dcc3SJonas Devlieghere self.assertTrue( 37*2238dcc3SJonas Devlieghere breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 38*2238dcc3SJonas Devlieghere ) 3999451b44SJordan Rupprecht 4099451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 41*2238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 4299451b44SJordan Rupprecht 4399451b44SJordan Rupprecht # We should be stopped due to the breakpoint. Get frame #0. 4499451b44SJordan Rupprecht process = target.GetProcess() 45*2238dcc3SJonas Devlieghere self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 46*2238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 4799451b44SJordan Rupprecht frame0 = thread.GetFrameAtIndex(0) 4899451b44SJordan Rupprecht 49*2238dcc3SJonas Devlieghere value = frame0.FindValue("g_char_ptr", lldb.eValueTypeVariableGlobal) 5099451b44SJordan Rupprecht pointee = value.CreateValueFromAddress( 51*2238dcc3SJonas Devlieghere "pointee", value.GetValueAsUnsigned(0), value.GetType().GetPointeeType() 52*2238dcc3SJonas Devlieghere ) 5399451b44SJordan Rupprecht # Watch for write to *g_char_ptr. 5499451b44SJordan Rupprecht error = lldb.SBError() 5599451b44SJordan Rupprecht watchpoint = value.WatchPointee(True, False, True, error) 56*2238dcc3SJonas Devlieghere self.assertTrue( 57*2238dcc3SJonas Devlieghere value and watchpoint, "Successfully found the pointer and set a watchpoint" 58*2238dcc3SJonas Devlieghere ) 5999451b44SJordan Rupprecht self.DebugSBValue(value) 6099451b44SJordan Rupprecht self.DebugSBValue(pointee) 6199451b44SJordan Rupprecht 6255a363feSDan Liew # Check some API calls return expected values 63*2238dcc3SJonas Devlieghere self.assertEqual( 64*2238dcc3SJonas Devlieghere watchpoint.GetWatchValueKind(), lldb.eWatchPointValueKindExpression 65*2238dcc3SJonas Devlieghere ) 6655a363feSDan Liew # FIXME: The spec should probably be 'g_char_ptr' 6755a363feSDan Liew self.assertEqual(watchpoint.GetWatchSpec(), None) 68*2238dcc3SJonas Devlieghere self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), "char") 6955a363feSDan Liew self.assertFalse(watchpoint.IsWatchingReads()) 7055a363feSDan Liew self.assertTrue(watchpoint.IsWatchingWrites()) 7155a363feSDan Liew 7299451b44SJordan Rupprecht # Hide stdout if not running with '-t' option. 7399451b44SJordan Rupprecht if not self.TraceOn(): 7499451b44SJordan Rupprecht self.HideStdout() 7599451b44SJordan Rupprecht 7699451b44SJordan Rupprecht print(watchpoint) 7799451b44SJordan Rupprecht 7899451b44SJordan Rupprecht # Continue. Expect the program to stop due to the variable being 7999451b44SJordan Rupprecht # written to. 8099451b44SJordan Rupprecht process.Continue() 8199451b44SJordan Rupprecht 82*2238dcc3SJonas Devlieghere if self.TraceOn(): 8399451b44SJordan Rupprecht lldbutil.print_stacktraces(process) 8499451b44SJordan Rupprecht 85*2238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) 8699451b44SJordan Rupprecht self.assertTrue(thread, "The thread stopped due to watchpoint") 8799451b44SJordan Rupprecht self.DebugSBValue(value) 8899451b44SJordan Rupprecht self.DebugSBValue(pointee) 8999451b44SJordan Rupprecht 9099451b44SJordan Rupprecht self.expect( 91*2238dcc3SJonas Devlieghere lldbutil.print_stacktrace(thread, string_buffer=True), 9299451b44SJordan Rupprecht exe=False, 93*2238dcc3SJonas Devlieghere substrs=[self.violating_func], 94*2238dcc3SJonas Devlieghere ) 9599451b44SJordan Rupprecht 9699451b44SJordan Rupprecht # This finishes our test. 97