TestWatchpointCommands.py revision 21b1984e161b0cadee331d32bfd721eccfdf4b1f
1"""
2Test watchpoint list, enable, disable, and delete commands.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9
10class WatchpointCommandsTestCase(TestBase):
11
12    mydir = os.path.join("functionalities", "watchpoint", "watchpoint_commands")
13
14    def setUp(self):
15        # Call super's setUp().
16        TestBase.setUp(self)
17        # Our simple source filename.
18        self.source = 'main.c'
19        # Find the line number to break inside main().
20        self.line = line_number(self.source, '// Set break point at this line.')
21        self.line2 = line_number(self.source, '// Set 2nd break point for disable_then_enable test case.')
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 = {'C_SOURCES': self.source, 'EXE': self.exe_name}
27
28    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
29    @dsym_test
30    def test_rw_watchpoint_with_dsym(self):
31        """Test read_write watchpoint and expect to stop two times."""
32        self.buildDsym(dictionary=self.d)
33        self.setTearDownCleanup(dictionary=self.d)
34        self.normal_read_write_watchpoint()
35
36    @dwarf_test
37    def test_rw_watchpoint_with_dwarf(self):
38        """Test read_write watchpoint and expect to stop two times."""
39        self.buildDwarf(dictionary=self.d)
40        self.setTearDownCleanup(dictionary=self.d)
41        self.normal_read_write_watchpoint()
42
43    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
44    @dsym_test
45    def test_rw_watchpoint_delete_with_dsym(self):
46        """Test delete watchpoint and expect not to stop for watchpoint."""
47        self.buildDsym(dictionary=self.d)
48        self.setTearDownCleanup(dictionary=self.d)
49        self.delete_read_write_watchpoint()
50
51    @dwarf_test
52    def test_rw_watchpoint_delete_with_dwarf(self):
53        """Test delete watchpoint and expect not to stop for watchpoint."""
54        self.buildDwarf(dictionary=self.d)
55        self.setTearDownCleanup(dictionary=self.d)
56        self.delete_read_write_watchpoint()
57
58    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
59    @dsym_test
60    def test_rw_watchpoint_set_ignore_count_with_dsym(self):
61        """Test watchpoint ignore count and expect to not to stop at all."""
62        self.buildDsym(dictionary=self.d)
63        self.setTearDownCleanup(dictionary=self.d)
64        self.ignore_read_write_watchpoint()
65
66    @dwarf_test
67    def test_rw_watchpoint_set_ignore_count_with_dwarf(self):
68        """Test watchpoint ignore count and expect to not to stop at all."""
69        self.buildDwarf(dictionary=self.d)
70        self.setTearDownCleanup(dictionary=self.d)
71        self.ignore_read_write_watchpoint()
72
73    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
74    @dsym_test
75    def test_rw_disable_after_first_stop_with_dsym(self):
76        """Test read_write watchpoint but disable it after the first stop."""
77        self.buildDsym(dictionary=self.d)
78        self.setTearDownCleanup(dictionary=self.d)
79        self.read_write_watchpoint_disable_after_first_stop()
80
81    @dwarf_test
82    def test_rw_disable_after_first_stop__with_dwarf(self):
83        """Test read_write watchpoint but disable it after the first stop."""
84        self.buildDwarf(dictionary=self.d)
85        self.setTearDownCleanup(dictionary=self.d)
86        self.read_write_watchpoint_disable_after_first_stop()
87
88    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
89    @dsym_test
90    def test_rw_disable_then_enable_with_dsym(self):
91        """Test read_write watchpoint, disable initially, then enable it."""
92        self.buildDsym(dictionary=self.d)
93        self.setTearDownCleanup(dictionary=self.d)
94        self.read_write_watchpoint_disable_then_enable()
95
96    @dwarf_test
97    def test_rw_disable_then_enable_with_dwarf(self):
98        """Test read_write watchpoint, disable initially, then enable it."""
99        self.buildDwarf(dictionary=self.d)
100        self.setTearDownCleanup(dictionary=self.d)
101        self.read_write_watchpoint_disable_then_enable()
102
103    def normal_read_write_watchpoint(self):
104        """Do read_write watchpoint and expect to stop two times."""
105        exe = os.path.join(os.getcwd(), self.exe_name)
106        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
107
108        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
109        self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED,
110            startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
111                       (self.source, self.line))
112
113        # Run the program.
114        self.runCmd("run", RUN_SUCCEEDED)
115
116        # We should be stopped again due to the breakpoint.
117        # The stop reason of the thread should be breakpoint.
118        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
119            substrs = ['stopped',
120                       'stop reason = breakpoint'])
121
122        # Now let's set a read_write-type watchpoint for 'global'.
123        # There should be two watchpoint hits (see main.c).
124        self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
125            substrs = ['Watchpoint created', 'size = 4', 'type = rw',
126                       '%s:%d' % (self.source, self.decl)])
127
128        # Use the '-v' option to do verbose listing of the watchpoint.
129        # The hit count should be 0 initially.
130        self.expect("watchpoint list -v",
131            substrs = ['hit_count = 0'])
132
133        self.runCmd("process continue")
134
135        # We should be stopped again due to the watchpoint (read_write type).
136        # The stop reason of the thread should be watchpoint.
137        self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
138            substrs = ['stop reason = watchpoint'])
139
140        self.runCmd("process continue")
141
142        # We should be stopped again due to the watchpoint (read_write type).
143        # The stop reason of the thread should be watchpoint.
144        self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
145            substrs = ['stop reason = watchpoint'])
146
147        self.runCmd("process continue")
148
149        # There should be no more watchpoint hit and the process status should
150        # be 'exited'.
151        self.expect("process status",
152            substrs = ['exited'])
153
154        # Use the '-v' option to do verbose listing of the watchpoint.
155        # The hit count should now be 2.
156        self.expect("watchpoint list -v",
157            substrs = ['hit_count = 2'])
158
159    def delete_read_write_watchpoint(self):
160        """Do delete watchpoint immediately and expect not to stop for watchpoint."""
161        exe = os.path.join(os.getcwd(), self.exe_name)
162        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
163
164        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
165        self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED,
166            startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
167                       (self.source, self.line))
168
169        # Run the program.
170        self.runCmd("run", RUN_SUCCEEDED)
171
172        # We should be stopped again due to the breakpoint.
173        # The stop reason of the thread should be breakpoint.
174        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
175            substrs = ['stopped',
176                       'stop reason = breakpoint'])
177
178        # Now let's set a read_write-type watchpoint for 'global'.
179        # There should be two watchpoint hits (see main.c).
180        self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
181            substrs = ['Watchpoint created', 'size = 4', 'type = rw',
182                       '%s:%d' % (self.source, self.decl)])
183
184        # Delete the watchpoint immediately, but set auto-confirm to true first.
185        self.runCmd("settings set auto-confirm true")
186        self.expect("watchpoint delete",
187            substrs = ['All watchpoints removed.'])
188        # Restore the original setting of auto-confirm.
189        self.runCmd("settings set -r auto-confirm")
190
191        # Use the '-v' option to do verbose listing of the watchpoint.
192        self.runCmd("watchpoint list -v")
193
194        self.runCmd("process continue")
195
196        # There should be no more watchpoint hit and the process status should
197        # be 'exited'.
198        self.expect("process status",
199            substrs = ['exited'])
200
201    def ignore_read_write_watchpoint(self):
202        """Test watchpoint ignore count and expect to not to stop at all."""
203        exe = os.path.join(os.getcwd(), self.exe_name)
204        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
205
206        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
207        self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED,
208            startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
209                       (self.source, self.line))
210
211        # Run the program.
212        self.runCmd("run", RUN_SUCCEEDED)
213
214        # We should be stopped again due to the breakpoint.
215        # The stop reason of the thread should be breakpoint.
216        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
217            substrs = ['stopped',
218                       'stop reason = breakpoint'])
219
220        # Now let's set a read_write-type watchpoint for 'global'.
221        # There should be two watchpoint hits (see main.c).
222        self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
223            substrs = ['Watchpoint created', 'size = 4', 'type = rw',
224                       '%s:%d' % (self.source, self.decl)])
225
226        # Set the ignore count of the watchpoint immediately.
227        self.expect("watchpoint ignore -i 2",
228            substrs = ['All watchpoints ignored.'])
229
230        # Use the '-v' option to do verbose listing of the watchpoint.
231        # Expect to find an ignore_count of 2.
232        self.expect("watchpoint list -v",
233            substrs = ['hit_count = 0', 'ignore_count = 2'])
234
235        self.runCmd("process continue")
236
237        # There should be no more watchpoint hit and the process status should
238        # be 'exited'.
239        self.expect("process status",
240            substrs = ['exited'])
241
242        # Use the '-v' option to do verbose listing of the watchpoint.
243        # Expect to find a hit_count of 2 as well.
244        self.expect("watchpoint list -v",
245            substrs = ['hit_count = 2', 'ignore_count = 2'])
246
247    def read_write_watchpoint_disable_after_first_stop(self):
248        """Do read_write watchpoint but disable it after the first stop."""
249        exe = os.path.join(os.getcwd(), self.exe_name)
250        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
251
252        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
253        self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED,
254            startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
255                       (self.source, self.line))
256
257        # Run the program.
258        self.runCmd("run", RUN_SUCCEEDED)
259
260        # We should be stopped again due to the breakpoint.
261        # The stop reason of the thread should be breakpoint.
262        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
263            substrs = ['stopped',
264                       'stop reason = breakpoint'])
265
266        # Now let's set a read_write-type watchpoint for 'global'.
267        # There should be two watchpoint hits (see main.c).
268        self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
269            substrs = ['Watchpoint created', 'size = 4', 'type = rw',
270                       '%s:%d' % (self.source, self.decl)])
271
272        # Use the '-v' option to do verbose listing of the watchpoint.
273        # The hit count should be 0 initially.
274        self.expect("watchpoint list -v",
275            substrs = ['state = enabled', 'hit_count = 0'])
276
277        self.runCmd("process continue")
278
279        # We should be stopped again due to the watchpoint (read_write type).
280        # The stop reason of the thread should be watchpoint.
281        self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
282            substrs = ['stop reason = watchpoint'])
283
284        # Before continuing, we'll disable the watchpoint, which means we won't
285        # stop agian after this.
286        self.runCmd("watchpoint disable")
287
288        self.expect("watchpoint list -v",
289            substrs = ['state = disabled', 'hit_count = 1'])
290
291        self.runCmd("process continue")
292
293        # There should be no more watchpoint hit and the process status should
294        # be 'exited'.
295        self.expect("process status",
296            substrs = ['exited'])
297
298        # Use the '-v' option to do verbose listing of the watchpoint.
299        # The hit count should be 1.
300        self.expect("watchpoint list -v",
301            substrs = ['hit_count = 1'])
302
303    def read_write_watchpoint_disable_then_enable(self):
304        """Do read_write watchpoint, disable initially, then enable it."""
305        exe = os.path.join(os.getcwd(), self.exe_name)
306        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
307
308        # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
309        self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED,
310            startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" %
311                       (self.source, self.line))
312        self.expect("breakpoint set -l %d" % self.line2, BREAKPOINT_CREATED,
313            startstr = "Breakpoint created: 2: file ='%s', line = %d, locations = 1" %
314                       (self.source, self.line2))
315
316        # Run the program.
317        self.runCmd("run", RUN_SUCCEEDED)
318
319        # We should be stopped again due to the breakpoint.
320        # The stop reason of the thread should be breakpoint.
321        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
322            substrs = ['stopped',
323                       'stop reason = breakpoint'])
324
325        # Now let's set a read_write-type watchpoint for 'global'.
326        # There should be two watchpoint hits (see main.c).
327        self.expect("watchpoint set variable -w read_write global", WATCHPOINT_CREATED,
328            substrs = ['Watchpoint created', 'size = 4', 'type = rw',
329                       '%s:%d' % (self.source, self.decl)])
330
331        # Immediately, we disable the watchpoint.  We won't be stopping due to a
332        # watchpoint after this.
333        self.runCmd("watchpoint disable")
334
335        # Use the '-v' option to do verbose listing of the watchpoint.
336        # The hit count should be 0 initially.
337        self.expect("watchpoint list -v",
338            substrs = ['state = disabled', 'hit_count = 0'])
339
340        self.runCmd("process continue")
341
342        # We should be stopped again due to the breakpoint.
343        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
344            substrs = ['stop reason = breakpoint'])
345
346        # Before continuing, we'll enable the watchpoint, which means we will
347        # stop agian after this.
348        self.runCmd("watchpoint enable")
349
350        self.expect("watchpoint list -v",
351            substrs = ['state = enabled', 'hit_count = 0'])
352
353        self.runCmd("process continue")
354
355        # We should be stopped again due to the watchpoint (read_write type).
356        # The stop reason of the thread should be watchpoint.
357        self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
358            substrs = ['stop reason = watchpoint'])
359
360        self.runCmd("process continue")
361
362        # There should be no more watchpoint hit and the process status should
363        # be 'exited'.
364        self.expect("process status",
365            substrs = ['exited'])
366
367        # Use the '-v' option to do verbose listing of the watchpoint.
368        # The hit count should be 1.
369        self.expect("watchpoint list -v",
370            substrs = ['hit_count = 1'])
371
372
373if __name__ == '__main__':
374    import atexit
375    lldb.SBDebugger.Initialize()
376    atexit.register(lambda: lldb.SBDebugger.Terminate())
377    unittest2.main()
378