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