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