199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtUse lldb Python SBValue API to create a watchpoint for read_write of 'globl' var. 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 SetWatchpointAPITestCase(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.c" 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.") 2155a363feSDan Liew self.build() 2299451b44SJordan Rupprecht 2399451b44SJordan Rupprecht # Read-write watchpoints not supported on SystemZ 24*2238dcc3SJonas Devlieghere @expectedFailureAll(archs=["s390x"]) 2599451b44SJordan Rupprecht def test_watch_val(self): 2699451b44SJordan Rupprecht """Exercise SBValue.Watch() API to set a watchpoint.""" 2755a363feSDan Liew self._test_watch_val(variable_watchpoint=False) 2855a363feSDan Liew pass 2955a363feSDan Liew 30*2238dcc3SJonas Devlieghere @expectedFailureAll(archs=["s390x"]) 3155a363feSDan Liew def test_watch_variable(self): 3255a363feSDan Liew """ 3355a363feSDan Liew Exercise some watchpoint APIs when the watchpoint 3455a363feSDan Liew is created as a variable watchpoint. 3555a363feSDan Liew """ 3655a363feSDan Liew self._test_watch_val(variable_watchpoint=True) 3755a363feSDan Liew 3855a363feSDan Liew def _test_watch_val(self, variable_watchpoint): 3999451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 4099451b44SJordan Rupprecht 4199451b44SJordan Rupprecht # Create a target by the debugger. 4299451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 4399451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 4499451b44SJordan Rupprecht 4599451b44SJordan Rupprecht # Now create a breakpoint on main.c. 4699451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 47*2238dcc3SJonas Devlieghere self.assertTrue( 48*2238dcc3SJonas Devlieghere breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 49*2238dcc3SJonas Devlieghere ) 5099451b44SJordan Rupprecht 5199451b44SJordan Rupprecht # Now launch the process, and do not stop at the entry point. 52*2238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 5399451b44SJordan Rupprecht 5499451b44SJordan Rupprecht # We should be stopped due to the breakpoint. Get frame #0. 5599451b44SJordan Rupprecht process = target.GetProcess() 56*2238dcc3SJonas Devlieghere self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 57*2238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 5899451b44SJordan Rupprecht frame0 = thread.GetFrameAtIndex(0) 5999451b44SJordan Rupprecht 6099451b44SJordan Rupprecht # Watch 'global' for read and write. 6155a363feSDan Liew if variable_watchpoint: 6255a363feSDan Liew # FIXME: There should probably be an API to create a 6355a363feSDan Liew # variable watchpoint. 64*2238dcc3SJonas Devlieghere self.runCmd("watchpoint set variable -w read_write -- global") 6555a363feSDan Liew watchpoint = target.GetWatchpointAtIndex(0) 66*2238dcc3SJonas Devlieghere self.assertEqual( 67*2238dcc3SJonas Devlieghere watchpoint.GetWatchValueKind(), lldb.eWatchPointValueKindVariable 68*2238dcc3SJonas Devlieghere ) 69*2238dcc3SJonas Devlieghere self.assertEqual(watchpoint.GetWatchSpec(), "global") 7055a363feSDan Liew # Synthesize an SBValue from the watchpoint 71*2238dcc3SJonas Devlieghere watchpoint_addr = lldb.SBAddress(watchpoint.GetWatchAddress(), target) 7255a363feSDan Liew value = target.CreateValueFromAddress( 73*2238dcc3SJonas Devlieghere watchpoint.GetWatchSpec(), watchpoint_addr, watchpoint.GetType() 74*2238dcc3SJonas Devlieghere ) 7555a363feSDan Liew else: 76*2238dcc3SJonas Devlieghere value = frame0.FindValue("global", lldb.eValueTypeVariableGlobal) 7799451b44SJordan Rupprecht error = lldb.SBError() 7899451b44SJordan Rupprecht watchpoint = value.Watch(True, True, True, error) 79*2238dcc3SJonas Devlieghere self.assertTrue( 80*2238dcc3SJonas Devlieghere value and watchpoint, 81*2238dcc3SJonas Devlieghere "Successfully found the variable and set a watchpoint", 82*2238dcc3SJonas Devlieghere ) 8399451b44SJordan Rupprecht self.DebugSBValue(value) 84*2238dcc3SJonas Devlieghere self.assertEqual( 85*2238dcc3SJonas Devlieghere watchpoint.GetWatchValueKind(), lldb.eWatchPointValueKindExpression 86*2238dcc3SJonas Devlieghere ) 8755a363feSDan Liew # FIXME: The spec should probably be '&global' given that the kind 8855a363feSDan Liew # is reported as eWatchPointValueKindExpression. If the kind is 8955a363feSDan Liew # actually supposed to be eWatchPointValueKindVariable then the spec 9055a363feSDan Liew # should probably be 'global'. 9155a363feSDan Liew self.assertEqual(watchpoint.GetWatchSpec(), None) 9255a363feSDan Liew 93*2238dcc3SJonas Devlieghere self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), "int32_t") 94*2238dcc3SJonas Devlieghere self.assertEqual(value.GetName(), "global") 9555a363feSDan Liew self.assertEqual(value.GetType(), watchpoint.GetType()) 9655a363feSDan Liew self.assertTrue(watchpoint.IsWatchingReads()) 9755a363feSDan Liew self.assertTrue(watchpoint.IsWatchingWrites()) 9899451b44SJordan Rupprecht 9999451b44SJordan Rupprecht # Hide stdout if not running with '-t' option. 10099451b44SJordan Rupprecht if not self.TraceOn(): 10199451b44SJordan Rupprecht self.HideStdout() 10299451b44SJordan Rupprecht 10399451b44SJordan Rupprecht print(watchpoint) 10499451b44SJordan Rupprecht 10599451b44SJordan Rupprecht # Continue. Expect the program to stop due to the variable being 10699451b44SJordan Rupprecht # written to. 10799451b44SJordan Rupprecht process.Continue() 10899451b44SJordan Rupprecht 109*2238dcc3SJonas Devlieghere if self.TraceOn(): 11099451b44SJordan Rupprecht lldbutil.print_stacktraces(process) 11199451b44SJordan Rupprecht 112*2238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) 11399451b44SJordan Rupprecht self.assertTrue(thread, "The thread stopped due to watchpoint") 11499451b44SJordan Rupprecht self.DebugSBValue(value) 11599451b44SJordan Rupprecht 11699451b44SJordan Rupprecht # Continue. Expect the program to stop due to the variable being read 11799451b44SJordan Rupprecht # from. 11899451b44SJordan Rupprecht process.Continue() 11999451b44SJordan Rupprecht 120*2238dcc3SJonas Devlieghere if self.TraceOn(): 12199451b44SJordan Rupprecht lldbutil.print_stacktraces(process) 12299451b44SJordan Rupprecht 123*2238dcc3SJonas Devlieghere thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint) 12499451b44SJordan Rupprecht self.assertTrue(thread, "The thread stopped due to watchpoint") 12599451b44SJordan Rupprecht self.DebugSBValue(value) 12699451b44SJordan Rupprecht 12799451b44SJordan Rupprecht # Continue the process. We don't expect the program to be stopped 12899451b44SJordan Rupprecht # again. 12999451b44SJordan Rupprecht process.Continue() 13099451b44SJordan Rupprecht 13199451b44SJordan Rupprecht # At this point, the inferior process should have exited. 132*2238dcc3SJonas Devlieghere self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) 13399451b44SJordan Rupprecht 13499451b44SJordan Rupprecht self.dbg.DeleteTarget(target) 13599451b44SJordan Rupprecht self.assertFalse(watchpoint.IsValid()) 136