201 lines · python
1"""2Test 'watchpoint command'.3"""4 5 6import os7import lldb8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10from lldbsuite.test import lldbutil11 12 13class WatchpointPythonCommandTestCase(TestBase):14 NO_DEBUG_INFO_TESTCASE = True15 16 def setUp(self):17 # Call super's setUp().18 TestBase.setUp(self)19 # Our simple source filename.20 self.source = "main.cpp"21 # Find the line number to break inside main().22 self.line = line_number(self.source, "// Set break point at this line.")23 self.second_line = line_number(self.source, "// Set another breakpoint here.")24 # And the watchpoint variable declaration line number.25 self.decl = line_number(self.source, "// Watchpoint variable declaration.")26 # Build dictionary to have unique executable names for each test27 # method.28 self.exe_name = self.testMethodName29 self.d = {"CXX_SOURCES": self.source, "EXE": self.exe_name}30 31 def test_watchpoint_command(self):32 """Test 'watchpoint command'."""33 self.build(dictionary=self.d)34 self.setTearDownCleanup(dictionary=self.d)35 36 exe = self.getBuildArtifact(self.exe_name)37 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)38 39 # Add a breakpoint to set a watchpoint when stopped on the breakpoint.40 lldbutil.run_break_set_by_file_and_line(41 self, None, self.line, num_expected_locations=142 )43 44 # Run the program.45 self.runCmd("run", RUN_SUCCEEDED)46 47 # We should be stopped again due to the breakpoint.48 # The stop reason of the thread should be breakpoint.49 self.expect(50 "thread list",51 STOPPED_DUE_TO_BREAKPOINT,52 substrs=["stopped", "stop reason = breakpoint"],53 )54 55 # Now let's set a write-type watchpoint for 'global'.56 self.expect(57 "watchpoint set variable -w write global",58 WATCHPOINT_CREATED,59 substrs=[60 "Watchpoint created",61 "size = 4",62 "type = w",63 "%s:%d" % (self.source, self.decl),64 ],65 )66 67 self.runCmd(68 "watchpoint command add -s python 1 -o 'frame.EvaluateExpression(\"cookie = 777\")'"69 )70 71 # List the watchpoint command we just added.72 self.expect(73 "watchpoint command list 1",74 substrs=["frame.EvaluateExpression", "cookie = 777"],75 )76 77 # Use the '-v' option to do verbose listing of the watchpoint.78 # The hit count should be 0 initially.79 self.expect("watchpoint list -v", substrs=["hit_count = 0"])80 81 self.runCmd("process continue")82 83 # We should be stopped again due to the watchpoint (write type).84 # The stop reason of the thread should be watchpoint.85 self.expect(86 "thread backtrace",87 STOPPED_DUE_TO_WATCHPOINT,88 substrs=["stop reason = watchpoint"],89 )90 91 # Check that the watchpoint snapshoting mechanism is working.92 self.expect("watchpoint list -v", substrs=["old value: 0", "new value: 1"])93 94 # The watchpoint command "forced" our global variable 'cookie' to95 # become 777.96 self.expect(97 "frame variable --show-globals cookie",98 substrs=["(int32_t)", "cookie = 777"],99 )100 101 def test_continue_in_watchpoint_command(self):102 """Test continue in a watchpoint command."""103 self.build(dictionary=self.d)104 self.setTearDownCleanup(dictionary=self.d)105 106 exe = self.getBuildArtifact(self.exe_name)107 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)108 109 # Add a breakpoint to set a watchpoint when stopped on the breakpoint.110 lldbutil.run_break_set_by_file_and_line(111 self, None, self.line, num_expected_locations=1112 )113 114 # Run the program.115 self.runCmd("run", RUN_SUCCEEDED)116 117 # We should be stopped again due to the breakpoint.118 # The stop reason of the thread should be breakpoint.119 self.expect(120 "thread list",121 STOPPED_DUE_TO_BREAKPOINT,122 substrs=["stopped", "stop reason = breakpoint"],123 )124 125 # Now let's set a write-type watchpoint for 'global'.126 self.expect(127 "watchpoint set variable -w write global",128 WATCHPOINT_CREATED,129 substrs=[130 "Watchpoint created",131 "size = 4",132 "type = w",133 "%s:%d" % (self.source, self.decl),134 ],135 )136 137 cmd_script_file = os.path.join(self.getSourceDir(), "watchpoint_command.py")138 self.runCmd("command script import '%s'" % (cmd_script_file))139 140 self.runCmd("watchpoint command add -F watchpoint_command.watchpoint_command")141 142 # List the watchpoint command we just added.143 self.expect(144 "watchpoint command list 1",145 substrs=["watchpoint_command.watchpoint_command"],146 )147 148 self.runCmd("process continue")149 150 # We should be stopped again due to the watchpoint (write type).151 # The stop reason of the thread should be watchpoint.152 self.expect(153 "thread backtrace",154 STOPPED_DUE_TO_WATCHPOINT,155 substrs=["stop reason = watchpoint"],156 )157 158 # We should have hit the watchpoint once, set cookie to 888, since the159 # user callback returned True.160 self.expect(161 "frame variable --show-globals cookie",162 substrs=["(int32_t)", "cookie = 888"],163 )164 165 self.runCmd("process continue")166 167 # We should be stopped again due to the watchpoint (write type).168 # The stop reason of the thread should be watchpoint.169 self.expect(170 "thread backtrace",171 STOPPED_DUE_TO_WATCHPOINT,172 substrs=["stop reason = watchpoint"],173 )174 175 # We should have hit the watchpoint a second time, set cookie to 666,176 # even if the user callback didn't return anything and then continue.177 self.expect(178 "frame variable --show-globals cookie",179 substrs=["(int32_t)", "cookie = 666"],180 )181 182 # Add a breakpoint to set a watchpoint when stopped on the breakpoint.183 lldbutil.run_break_set_by_file_and_line(184 self, None, self.second_line, num_expected_locations=1185 )186 187 self.runCmd("process continue")188 189 self.expect(190 "thread backtrace",191 STOPPED_DUE_TO_BREAKPOINT,192 substrs=["stop reason = breakpoint"],193 )194 195 # We should have hit the watchpoint once, set cookie to 888, then continued to the196 # second hit and set it to 999197 self.expect(198 "frame variable --show-globals cookie",199 substrs=["(int32_t)", "cookie = 999"],200 )201