1f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen"""
2f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenTest 'watchpoint command'.
3f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen"""
4f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
5f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenimport os, time
6f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenimport unittest2
7f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenimport lldb
8f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenfrom lldbtest import *
9431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
10f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
11f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenclass WatchpointLLDBCommandTestCase(TestBase):
12f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
13f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    mydir = os.path.join("functionalities", "watchpoint", "watchpoint_commands", "command")
14f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
15f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    def setUp(self):
16f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Call super's setUp().
17f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        TestBase.setUp(self)
18f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Our simple source filename.
19f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.source = 'main.cpp'
20f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Find the line number to break inside main().
21f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.line = line_number(self.source, '// Set break point at this line.')
22f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # And the watchpoint variable declaration line number.
23f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.decl = line_number(self.source, '// Watchpoint variable declaration.')
24f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Build dictionary to have unique executable names for each test method.
25f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.exe_name = self.testMethodName
26f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
27f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
28f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
29f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    @dsym_test
30f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    def test_watchpoint_command_with_dsym(self):
31f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        """Test 'watchpoint command'."""
32f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.buildDsym(dictionary=self.d)
33f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.setTearDownCleanup(dictionary=self.d)
34f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.watchpoint_command()
35f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
363bf526ac0f51dda6f63be3421cd7de68720dd656Ed Maste    @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD
37f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    @dwarf_test
38f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    def test_watchpoint_command_with_dwarf(self):
39f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        """Test 'watchpoint command'."""
40f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.buildDwarf(dictionary=self.d)
41f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.setTearDownCleanup(dictionary=self.d)
42f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.watchpoint_command()
43f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
44258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
45258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen    @dsym_test
46258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen    def test_watchpoint_command_can_disable_a_watchpoint_with_dsym(self):
47258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        """Test that 'watchpoint command' action can disable a watchpoint after it is triggered."""
48258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.buildDsym(dictionary=self.d)
49258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.setTearDownCleanup(dictionary=self.d)
50258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.watchpoint_command_can_disable_a_watchpoint()
51258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
523bf526ac0f51dda6f63be3421cd7de68720dd656Ed Maste    @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD
53258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen    @dwarf_test
54258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen    def test_watchpoint_command_can_disable_a_watchpoint_with_dwarf(self):
55258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        """Test that 'watchpoint command' action can disable a watchpoint after it is triggered."""
56258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.buildDwarf(dictionary=self.d)
57258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.setTearDownCleanup(dictionary=self.d)
58258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.watchpoint_command_can_disable_a_watchpoint()
59258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
60f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    def watchpoint_command(self):
61f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        """Do 'watchpoint command add'."""
62f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        exe = os.path.join(os.getcwd(), self.exe_name)
63f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
64f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
65f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
66431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
67f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
68f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Run the program.
69f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.runCmd("run", RUN_SUCCEEDED)
70f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
71f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # We should be stopped again due to the breakpoint.
72f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # The stop reason of the thread should be breakpoint.
73f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
74f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            substrs = ['stopped',
75f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                       'stop reason = breakpoint'])
76f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
77f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Now let's set a write-type watchpoint for 'global'.
78f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
79f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            substrs = ['Watchpoint created', 'size = 4', 'type = w',
80f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                       '%s:%d' % (self.source, self.decl)])
81f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
829e98559420d8c7c248b0c75b48db65ffd878402bJohnny Chen        self.runCmd('watchpoint command add 1 -o "expr -- cookie = 777"')
83f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
84f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # List the watchpoint command we just added.
85f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.expect("watchpoint command list 1",
869e98559420d8c7c248b0c75b48db65ffd878402bJohnny Chen            substrs = ['expr -- cookie = 777'])
87f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
88f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # Use the '-v' option to do verbose listing of the watchpoint.
89f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # The hit count should be 0 initially.
90f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.expect("watchpoint list -v",
91f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            substrs = ['hit_count = 0'])
92f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
93f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.runCmd("process continue")
94f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
95f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # We should be stopped again due to the watchpoint (write type).
96f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        # The stop reason of the thread should be watchpoint.
97f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
98f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            substrs = ['stop reason = watchpoint'])
99f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
1009e98559420d8c7c248b0c75b48db65ffd878402bJohnny Chen        # Check that the watchpoint snapshoting mechanism is working.
1019e98559420d8c7c248b0c75b48db65ffd878402bJohnny Chen        self.expect("watchpoint list -v",
1029e376625d6354d77cd6240007f0d42034dd3f1eeJim Ingham            substrs = ['old value:', ' = 0',
1039e376625d6354d77cd6240007f0d42034dd3f1eeJim Ingham                       'new value:', ' = 1'])
1049e98559420d8c7c248b0c75b48db65ffd878402bJohnny Chen
1059e98559420d8c7c248b0c75b48db65ffd878402bJohnny Chen        # The watchpoint command "forced" our global variable 'cookie' to become 777.
1066475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        self.expect("frame variable --show-globals cookie",
1079e98559420d8c7c248b0c75b48db65ffd878402bJohnny Chen            substrs = ['(int32_t)', 'cookie = 777'])
108f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
109258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen    def watchpoint_command_can_disable_a_watchpoint(self):
110258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        """Test that 'watchpoint command' action can disable a watchpoint after it is triggered."""
111258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        exe = os.path.join(os.getcwd(), self.exe_name)
112258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
113258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
114258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
115431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1)
116258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
117258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # Run the program.
118258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.runCmd("run", RUN_SUCCEEDED)
119258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
120258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # We should be stopped again due to the breakpoint.
121258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # The stop reason of the thread should be breakpoint.
122258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
123258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen            substrs = ['stopped',
124258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen                       'stop reason = breakpoint'])
125258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
126258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # Now let's set a write-type watchpoint for 'global'.
127258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.expect("watchpoint set variable -w write global", WATCHPOINT_CREATED,
128258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen            substrs = ['Watchpoint created', 'size = 4', 'type = w',
129258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen                       '%s:%d' % (self.source, self.decl)])
130258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
131258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.runCmd('watchpoint command add 1 -o "watchpoint disable 1"')
132258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
133258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # List the watchpoint command we just added.
134258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.expect("watchpoint command list 1",
135258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen            substrs = ['watchpoint disable 1'])
136258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
137258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # Use the '-v' option to do verbose listing of the watchpoint.
138258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # The hit count should be 0 initially.
139258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.expect("watchpoint list -v",
140258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen            substrs = ['hit_count = 0'])
141258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
142258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.runCmd("process continue")
143258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
144258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # We should be stopped again due to the watchpoint (write type).
145258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # The stop reason of the thread should be watchpoint.
146258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
147258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen            substrs = ['stop reason = watchpoint'])
148258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
149258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # Check that the watchpoint has been disabled.
150258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.expect("watchpoint list -v",
151258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen            substrs = ['disabled'])
152258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
153258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.runCmd("process continue")
154258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
155258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # There should be no more watchpoint hit and the process status should
156258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        # be 'exited'.
157258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen        self.expect("process status",
158258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen            substrs = ['exited'])
159258db3ab3d02fc013f8674f3c20007c1e86b503dJohnny Chen
160f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
161f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenif __name__ == '__main__':
162f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    import atexit
163f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    lldb.SBDebugger.Initialize()
164f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
165f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    unittest2.main()
166