1""" 2Test lldb watchpoint that uses '-x size' to watch a pointed location with size. 3""" 4 5import os, time 6import re 7import unittest2 8import lldb 9from lldbtest import * 10import lldbutil 11 12class HelloWatchLocationTestCase(TestBase): 13 14 mydir = os.path.join("functionalities", "watchpoint", "hello_watchlocation") 15 16 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 17 @dsym_test 18 def test_hello_watchlocation_with_dsym(self): 19 """Test watching a location with '-x size' option.""" 20 self.buildDsym(dictionary=self.d) 21 self.setTearDownCleanup(dictionary=self.d) 22 self.hello_watchlocation() 23 24 @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD 25 @dwarf_test 26 def test_hello_watchlocation_with_dwarf(self): 27 """Test watching a location with '-x size' option.""" 28 self.buildDwarf(dictionary=self.d) 29 self.setTearDownCleanup(dictionary=self.d) 30 self.hello_watchlocation() 31 32 def setUp(self): 33 # Call super's setUp(). 34 TestBase.setUp(self) 35 # Our simple source filename. 36 self.source = 'main.cpp' 37 # Find the line number to break inside main(). 38 self.line = line_number(self.source, '// Set break point at this line.') 39 # This is for verifying that watch location works. 40 self.violating_func = "do_bad_thing_with_location"; 41 # Build dictionary to have unique executable names for each test method. 42 self.exe_name = self.testMethodName 43 self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name} 44 45 def hello_watchlocation(self): 46 """Test watching a location with '-x size' option.""" 47 exe = os.path.join(os.getcwd(), self.exe_name) 48 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 49 50 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 51 lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=False) 52 53 # Run the program. 54 self.runCmd("run", RUN_SUCCEEDED) 55 56 # We should be stopped again due to the breakpoint. 57 # The stop reason of the thread should be breakpoint. 58 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 59 substrs = ['stopped', 60 'stop reason = breakpoint']) 61 62 # Now let's set a write-type watchpoint pointed to by 'g_char_ptr'. 63 # The main.cpp, by design, misbehaves by not following the agreed upon 64 # protocol of using a mutex while accessing the global pool and by not 65 # incrmenting the global pool by 2. 66 self.expect("watchpoint set expression -w write -x 1 -- g_char_ptr", WATCHPOINT_CREATED, 67 substrs = ['Watchpoint created', 'size = 1', 'type = w']) 68 # Get a hold of the watchpoint id just created, it is used later on to 69 # match the watchpoint id which is expected to be fired. 70 match = re.match("Watchpoint created: Watchpoint (.*):", self.res.GetOutput().splitlines()[0]) 71 if match: 72 expected_wp_id = int(match.group(1), 0) 73 else: 74 self.fail("Grokking watchpoint id faailed!") 75 76 self.runCmd("expr unsigned val = *g_char_ptr; val") 77 self.expect(self.res.GetOutput().splitlines()[0], exe=False, 78 endstr = ' = 0') 79 80 self.runCmd("watchpoint set expression -w write -x 4 -- &g_thread_1") 81 82 # Use the '-v' option to do verbose listing of the watchpoint. 83 # The hit count should be 0 initially. 84 self.expect("watchpoint list -v", 85 substrs = ['hit_count = 0']) 86 87 self.runCmd("process continue") 88 89 # We should be stopped again due to the watchpoint (write type), but 90 # only once. The stop reason of the thread should be watchpoint. 91 self.expect("thread list", STOPPED_DUE_TO_WATCHPOINT, 92 substrs = ['stopped', 93 'stop reason = watchpoint %d' % expected_wp_id, 94 self.violating_func]) 95 96 # Switch to the thread stopped due to watchpoint and issue some commands. 97 self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint) 98 self.runCmd("thread backtrace") 99 self.runCmd("expr unsigned val = *g_char_ptr; val") 100 self.expect(self.res.GetOutput().splitlines()[0], exe=False, 101 endstr = ' = 1') 102 103 # Use the '-v' option to do verbose listing of the watchpoint. 104 # The hit count should now be 1. 105 self.expect("watchpoint list -v", 106 substrs = ['hit_count = 1']) 107 108 self.runCmd("thread backtrace all") 109 110 111if __name__ == '__main__': 112 import atexit 113 lldb.SBDebugger.Initialize() 114 atexit.register(lambda: lldb.SBDebugger.Terminate()) 115 unittest2.main() 116