136 lines · python
1"""2Use lldb Python SBValue API to create a watchpoint for read_write of 'globl' var.3"""4 5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class SetWatchpointAPITestCase(TestBase):12 NO_DEBUG_INFO_TESTCASE = True13 14 def setUp(self):15 # Call super's setUp().16 TestBase.setUp(self)17 # Our simple source filename.18 self.source = "main.c"19 # Find the line number to break inside main().20 self.line = line_number(self.source, "// Set break point at this line.")21 self.build()22 23 # Read-write watchpoints not supported on SystemZ24 @expectedFailureAll(archs=["s390x"])25 def test_watch_val(self):26 """Exercise SBValue.Watch() API to set a watchpoint."""27 self._test_watch_val(variable_watchpoint=False)28 pass29 30 @expectedFailureAll(archs=["s390x"])31 def test_watch_variable(self):32 """33 Exercise some watchpoint APIs when the watchpoint34 is created as a variable watchpoint.35 """36 self._test_watch_val(variable_watchpoint=True)37 38 def _test_watch_val(self, variable_watchpoint):39 exe = self.getBuildArtifact("a.out")40 41 # Create a target by the debugger.42 target = self.dbg.CreateTarget(exe)43 self.assertTrue(target, VALID_TARGET)44 45 # Now create a breakpoint on main.c.46 breakpoint = target.BreakpointCreateByLocation(self.source, self.line)47 self.assertTrue(48 breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT49 )50 51 # Now launch the process, and do not stop at the entry point.52 process = target.LaunchSimple(None, None, self.get_process_working_directory())53 54 # We should be stopped due to the breakpoint. Get frame #0.55 process = target.GetProcess()56 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)57 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)58 frame0 = thread.GetFrameAtIndex(0)59 60 # Watch 'global' for read and write.61 if variable_watchpoint:62 # FIXME: There should probably be an API to create a63 # variable watchpoint.64 self.runCmd("watchpoint set variable -w read_write -- global")65 watchpoint = target.GetWatchpointAtIndex(0)66 self.assertEqual(67 watchpoint.GetWatchValueKind(), lldb.eWatchPointValueKindVariable68 )69 self.assertEqual(watchpoint.GetWatchSpec(), "global")70 # Synthesize an SBValue from the watchpoint71 watchpoint_addr = lldb.SBAddress(watchpoint.GetWatchAddress(), target)72 value = target.CreateValueFromAddress(73 watchpoint.GetWatchSpec(), watchpoint_addr, watchpoint.GetType()74 )75 else:76 value = frame0.FindValue("global", lldb.eValueTypeVariableGlobal)77 error = lldb.SBError()78 watchpoint = value.Watch(True, True, True, error)79 self.assertTrue(80 value and watchpoint,81 "Successfully found the variable and set a watchpoint",82 )83 self.DebugSBValue(value)84 self.assertEqual(85 watchpoint.GetWatchValueKind(), lldb.eWatchPointValueKindExpression86 )87 # FIXME: The spec should probably be '&global' given that the kind88 # is reported as eWatchPointValueKindExpression. If the kind is89 # actually supposed to be eWatchPointValueKindVariable then the spec90 # should probably be 'global'.91 self.assertEqual(watchpoint.GetWatchSpec(), None)92 93 self.assertEqual(watchpoint.GetType().GetDisplayTypeName(), "int32_t")94 self.assertEqual(value.GetName(), "global")95 self.assertEqual(value.GetType(), watchpoint.GetType())96 self.assertTrue(watchpoint.IsWatchingReads())97 self.assertTrue(watchpoint.IsWatchingWrites())98 99 # Hide stdout if not running with '-t' option.100 if not self.TraceOn():101 self.HideStdout()102 103 print(watchpoint)104 105 # Continue. Expect the program to stop due to the variable being106 # written to.107 process.Continue()108 109 if self.TraceOn():110 lldbutil.print_stacktraces(process)111 112 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)113 self.assertTrue(thread, "The thread stopped due to watchpoint")114 self.DebugSBValue(value)115 116 # Continue. Expect the program to stop due to the variable being read117 # from.118 process.Continue()119 120 if self.TraceOn():121 lldbutil.print_stacktraces(process)122 123 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)124 self.assertTrue(thread, "The thread stopped due to watchpoint")125 self.DebugSBValue(value)126 127 # Continue the process. We don't expect the program to be stopped128 # again.129 process.Continue()130 131 # At this point, the inferior process should have exited.132 self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)133 134 self.dbg.DeleteTarget(target)135 self.assertFalse(watchpoint.IsValid())136