1""" 2Use lldb Python SBtarget.WatchAddress() API to create a watchpoint for write of '*g_char_ptr'. 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 TargetWatchAddressAPITestCase(TestBase): 15 NO_DEBUG_INFO_TESTCASE = True 16 17 def setUp(self): 18 # Call super's setUp(). 19 TestBase.setUp(self) 20 # Our simple source filename. 21 self.source = 'main.cpp' 22 # Find the line number to break inside main(). 23 self.line = line_number( 24 self.source, '// Set break point at this line.') 25 # This is for verifying that watch location works. 26 self.violating_func = "do_bad_thing_with_location" 27 28 def test_watch_address(self): 29 """Exercise SBTarget.WatchAddress() API to set a watchpoint.""" 30 self.build() 31 exe = self.getBuildArtifact("a.out") 32 33 # Create a target by the debugger. 34 target = self.dbg.CreateTarget(exe) 35 self.assertTrue(target, VALID_TARGET) 36 37 # Now create a breakpoint on main.c. 38 breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 39 self.assertTrue(breakpoint and 40 breakpoint.GetNumLocations() == 1, 41 VALID_BREAKPOINT) 42 43 # Now launch the process, and do not stop at the entry point. 44 process = target.LaunchSimple( 45 None, None, self.get_process_working_directory()) 46 47 # We should be stopped due to the breakpoint. Get frame #0. 48 process = target.GetProcess() 49 self.assertState(process.GetState(), lldb.eStateStopped, 50 PROCESS_STOPPED) 51 thread = lldbutil.get_stopped_thread( 52 process, lldb.eStopReasonBreakpoint) 53 frame0 = thread.GetFrameAtIndex(0) 54 55 value = frame0.FindValue('g_char_ptr', 56 lldb.eValueTypeVariableGlobal) 57 pointee = value.CreateValueFromAddress( 58 "pointee", 59 value.GetValueAsUnsigned(0), 60 value.GetType().GetPointeeType()) 61 # Watch for write to *g_char_ptr. 62 error = lldb.SBError() 63 watchpoint = target.WatchAddress( 64 value.GetValueAsUnsigned(), 1, False, True, error) 65 self.assertTrue(value and watchpoint, 66 "Successfully found the pointer and set a watchpoint") 67 self.DebugSBValue(value) 68 self.DebugSBValue(pointee) 69 70 # Hide stdout if not running with '-t' option. 71 if not self.TraceOn(): 72 self.HideStdout() 73 74 print(watchpoint) 75 76 # Continue. Expect the program to stop due to the variable being 77 # written to. 78 process.Continue() 79 80 if (self.TraceOn()): 81 lldbutil.print_stacktraces(process) 82 83 thread = lldbutil.get_stopped_thread( 84 process, lldb.eStopReasonWatchpoint) 85 self.assertTrue(thread, "The thread stopped due to watchpoint") 86 self.DebugSBValue(value) 87 self.DebugSBValue(pointee) 88 89 self.expect( 90 lldbutil.print_stacktrace( 91 thread, 92 string_buffer=True), 93 exe=False, 94 substrs=[ 95 self.violating_func]) 96 97 # This finishes our test. 98 99 # No size constraint on MIPS for watches 100 @skipIf(archs=['mips', 'mipsel', 'mips64', 'mips64el']) 101 @skipIf(archs=['s390x']) # Likewise on SystemZ 102 def test_watch_address_with_invalid_watch_size(self): 103 """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" 104 self.build() 105 exe = self.getBuildArtifact("a.out") 106 107 # Create a target by the debugger. 108 target = self.dbg.CreateTarget(exe) 109 self.assertTrue(target, VALID_TARGET) 110 111 # Now create a breakpoint on main.c. 112 breakpoint = target.BreakpointCreateByLocation(self.source, self.line) 113 self.assertTrue(breakpoint and 114 breakpoint.GetNumLocations() == 1, 115 VALID_BREAKPOINT) 116 117 # Now launch the process, and do not stop at the entry point. 118 process = target.LaunchSimple( 119 None, None, self.get_process_working_directory()) 120 121 # We should be stopped due to the breakpoint. Get frame #0. 122 process = target.GetProcess() 123 self.assertState(process.GetState(), lldb.eStateStopped, 124 PROCESS_STOPPED) 125 thread = lldbutil.get_stopped_thread( 126 process, lldb.eStopReasonBreakpoint) 127 frame0 = thread.GetFrameAtIndex(0) 128 129 value = frame0.FindValue('g_char_ptr', 130 lldb.eValueTypeVariableGlobal) 131 pointee = value.CreateValueFromAddress( 132 "pointee", 133 value.GetValueAsUnsigned(0), 134 value.GetType().GetPointeeType()) 135 # Watch for write to *g_char_ptr. 136 error = lldb.SBError() 137 watchpoint = target.WatchAddress( 138 value.GetValueAsUnsigned(), 365, False, True, error) 139 self.assertFalse(watchpoint) 140 self.expect(error.GetCString(), exe=False, 141 substrs=['watch size of %d is not supported' % 365]) 142