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