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