1""" 2Use lldb Python SBValue API to create a watchpoint for read_write of 'globl' var. 3""" 4 5from __future__ import print_function 6 7 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbutil 12 13 14class SetWatchpointAPITestCase(TestBase): 15 16 mydir = TestBase.compute_mydir(__file__) 17 NO_DEBUG_INFO_TESTCASE = True 18 19 def setUp(self): 20 # Call super's setUp(). 21 TestBase.setUp(self) 22 # Our simple source filename. 23 self.source = 'main.c' 24 # Find the line number to break inside main(). 25 self.line = line_number( 26 self.source, '// Set break point at this line.') 27 28 @add_test_categories(['pyapi']) 29 # Read-write watchpoints not supported on SystemZ 30 @expectedFailureAll(archs=['s390x']) 31 def test_watch_val(self): 32 """Exercise SBValue.Watch() API to set a watchpoint.""" 33 self.build() 34 exe = self.getBuildArtifact("a.out") 35 36 # Create a target by the debugger. 37 target = self.dbg.CreateTarget(exe) 38 self.assertTrue(target, VALID_TARGET) 39 40 # Now create a breakpoint on main.c. 41 breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 42 self.assertTrue(breakpoint and 43 breakpoint.GetNumLocations() == 1, 44 VALID_BREAKPOINT) 45 46 # Now launch the process, and do not stop at the entry point. 47 process = target.LaunchSimple( 48 None, None, self.get_process_working_directory()) 49 50 # We should be stopped due to the breakpoint. Get frame #0. 51 process = target.GetProcess() 52 self.assertTrue(process.GetState() == lldb.eStateStopped, 53 PROCESS_STOPPED) 54 thread = lldbutil.get_stopped_thread( 55 process, lldb.eStopReasonBreakpoint) 56 frame0 = thread.GetFrameAtIndex(0) 57 58 # Watch 'global' for read and write. 59 value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) 60 error = lldb.SBError() 61 watchpoint = value.Watch(True, True, True, error) 62 self.assertTrue(value and watchpoint, 63 "Successfully found the variable and set a watchpoint") 64 self.DebugSBValue(value) 65 66 # Hide stdout if not running with '-t' option. 67 if not self.TraceOn(): 68 self.HideStdout() 69 70 print(watchpoint) 71 72 # Continue. Expect the program to stop due to the variable being 73 # written to. 74 process.Continue() 75 76 if (self.TraceOn()): 77 lldbutil.print_stacktraces(process) 78 79 thread = lldbutil.get_stopped_thread( 80 process, lldb.eStopReasonWatchpoint) 81 self.assertTrue(thread, "The thread stopped due to watchpoint") 82 self.DebugSBValue(value) 83 84 # Continue. Expect the program to stop due to the variable being read 85 # from. 86 process.Continue() 87 88 if (self.TraceOn()): 89 lldbutil.print_stacktraces(process) 90 91 thread = lldbutil.get_stopped_thread( 92 process, lldb.eStopReasonWatchpoint) 93 self.assertTrue(thread, "The thread stopped due to watchpoint") 94 self.DebugSBValue(value) 95 96 # Continue the process. We don't expect the program to be stopped 97 # again. 98 process.Continue() 99 100 # At this point, the inferior process should have exited. 101 self.assertTrue( 102 process.GetState() == lldb.eStateExited, 103 PROCESS_EXITED) 104 105 self.dbg.DeleteTarget(target) 106 107 # The next check relies on the watchpoint being destructed, which does 108 # not happen during replay because objects are intentionally kept alive 109 # forever. 110 if not configuration.is_reproducer(): 111 self.assertFalse(watchpoint.IsValid()) 112