1 """ 2 Test 'watchpoint command'. 3 """ 4 5 import os, time 6 import unittest2 7 import lldb 8 from lldbtest import * 9 import lldbutil 10 11 class WatchpointLLDBCommandTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "watchpoint", "watchpoint_commands", "command") 14 15 def setUp(self): 16 # Call super's setUp(). 17 TestBase.setUp(self) 18 # Our simple source filename. 19 self.source = 'main.cpp' 20 # Find the line number to break inside main(). 21 self.line = line_number(self.source, '// Set break point at this line.') 22 # And the watchpoint variable declaration line number. 23 self.decl = line_number(self.source, '// Watchpoint variable declaration.') 24 # Build dictionary to have unique executable names for each test method. 25 self.exe_name = self.testMethodName 26 self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name} 27 28 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 29 @dsym_test 30 def test_watchpoint_command_with_dsym(self): 31 """Test 'watchpoint command'.""" 32 self.buildDsym(dictionary=self.d) 33 self.setTearDownCleanup(dictionary=self.d) 34 self.watchpoint_command() 35 36 @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD 37 @dwarf_test 38 def test_watchpoint_command_with_dwarf(self): 39 """Test 'watchpoint command'.""" 40 self.buildDwarf(dictionary=self.d) 41 self.setTearDownCleanup(dictionary=self.d) 42 self.watchpoint_command() 43 44 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 45 @dsym_test 46 def test_watchpoint_command_can_disable_a_watchpoint_with_dsym(self): 47 """Test that 'watchpoint command' action can disable a watchpoint after it is triggered.""" 48 self.buildDsym(dictionary=self.d) 49 self.setTearDownCleanup(dictionary=self.d) 50 self.watchpoint_command_can_disable_a_watchpoint() 51 52 @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD 53 @dwarf_test 54 def test_watchpoint_command_can_disable_a_watchpoint_with_dwarf(self): 55 """Test that 'watchpoint command' action can disable a watchpoint after it is triggered.""" 56 self.buildDwarf(dictionary=self.d) 57 self.setTearDownCleanup(dictionary=self.d) 58 self.watchpoint_command_can_disable_a_watchpoint() 59 60 def watchpoint_command(self): 61 """Do 'watchpoint command add'.""" 62 exe = os.path.join(os.getcwd(), self.exe_name) 63 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 64 65 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 66 lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1) 67 68 # Run the program. 69 self.runCmd("run", RUN_SUCCEEDED) 70 71 # We should be stopped again due to the breakpoint. 72 # The stop reason of the thread should be breakpoint. 73 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 74 substrs = ['stopped', 75 'stop reason = breakpoint']) 76 77 # Now let's set a write-type watchpoint for 'global'. 78 self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED, 79 substrs = ['Watchpoint created', 'size = 4', 'type = w', 80 '%s:%d' % (self.source, self.decl)]) 81 82 self.runCmd('watchpoint command add 1 -o "expr -- cookie = 777"') 83 84 # List the watchpoint command we just added. 85 self.expect("watchpoint command list 1", 86 substrs = ['expr -- cookie = 777']) 87 88 # Use the '-v' option to do verbose listing of the watchpoint. 89 # The hit count should be 0 initially. 90 self.expect("watchpoint list -v", 91 substrs = ['hit_count = 0']) 92 93 self.runCmd("process continue") 94 95 # We should be stopped again due to the watchpoint (write type). 96 # The stop reason of the thread should be watchpoint. 97 self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT, 98 substrs = ['stop reason = watchpoint']) 99 100 # Check that the watchpoint snapshoting mechanism is working. 101 self.expect("watchpoint list -v", 102 substrs = ['old value:', ' = 0', 103 'new value:', ' = 1']) 104 105 # The watchpoint command "forced" our global variable 'cookie' to become 777. 106 self.expect("frame variable --show-globals cookie", 107 substrs = ['(int32_t)', 'cookie = 777']) 108 109 def watchpoint_command_can_disable_a_watchpoint(self): 110 """Test that 'watchpoint command' action can disable a watchpoint after it is triggered.""" 111 exe = os.path.join(os.getcwd(), self.exe_name) 112 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 113 114 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 115 lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1) 116 117 # Run the program. 118 self.runCmd("run", RUN_SUCCEEDED) 119 120 # We should be stopped again due to the breakpoint. 121 # The stop reason of the thread should be breakpoint. 122 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 123 substrs = ['stopped', 124 'stop reason = breakpoint']) 125 126 # Now let's set a write-type watchpoint for 'global'. 127 self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED, 128 substrs = ['Watchpoint created', 'size = 4', 'type = w', 129 '%s:%d' % (self.source, self.decl)]) 130 131 self.runCmd('watchpoint command add 1 -o "watchpoint disable 1"') 132 133 # List the watchpoint command we just added. 134 self.expect("watchpoint command list 1", 135 substrs = ['watchpoint disable 1']) 136 137 # Use the '-v' option to do verbose listing of the watchpoint. 138 # The hit count should be 0 initially. 139 self.expect("watchpoint list -v", 140 substrs = ['hit_count = 0']) 141 142 self.runCmd("process continue") 143 144 # We should be stopped again due to the watchpoint (write type). 145 # The stop reason of the thread should be watchpoint. 146 self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT, 147 substrs = ['stop reason = watchpoint']) 148 149 # Check that the watchpoint has been disabled. 150 self.expect("watchpoint list -v", 151 substrs = ['disabled']) 152 153 self.runCmd("process continue") 154 155 # There should be no more watchpoint hit and the process status should 156 # be 'exited'. 157 self.expect("process status", 158 substrs = ['exited']) 159 160 161 if __name__ == '__main__': 162 import atexit 163 lldb.SBDebugger.Initialize() 164 atexit.register(lambda: lldb.SBDebugger.Terminate()) 165 unittest2.main() 166