120 lines · python
1"""2Test lldb watchpoint that uses '-s size' to watch a pointed location with size.3"""4 5 6import re7import lldb8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10from lldbsuite.test import lldbutil11 12 13class HelloWatchLocationTestCase(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 # This is for verifying that watch location works.24 self.violating_func = "do_bad_thing_with_location"25 # Build dictionary to have unique executable names for each test26 # method.27 self.exe_name = self.testMethodName28 self.d = {"CXX_SOURCES": self.source, "EXE": self.exe_name}29 30 # on arm64 targets, lldb has incorrect hit-count / ignore-counts31 # for watchpoints when they are hit with multiple threads at32 # the same time. Tracked as llvm.org/pr4943333 # or rdar://93863107 inside Apple.34 def affected_by_radar_93863107(self):35 return (36 self.getArchitecture() in ["arm64", "arm64e"]37 ) and self.platformIsDarwin()38 39 # Most of the MIPS boards provide only one H/W watchpoints, and S/W40 # watchpoints are not supported yet41 @expectedFailureAll(triple=re.compile("^mips"))42 # SystemZ and PowerPC also currently supports only one H/W watchpoint43 @expectedFailureAll(archs=["powerpc64le", "s390x"])44 @skipIfWindows # This test is flaky on Windows45 def test_hello_watchlocation(self):46 """Test watching a location with '-s size' option."""47 self.build(dictionary=self.d)48 self.setTearDownCleanup(dictionary=self.d)49 exe = self.getBuildArtifact(self.exe_name)50 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)51 52 # Add a breakpoint to set a watchpoint when stopped on the breakpoint.53 lldbutil.run_break_set_by_file_and_line(54 self, None, self.line, num_expected_locations=1, loc_exact=False55 )56 57 # Run the program.58 self.runCmd("run", RUN_SUCCEEDED)59 60 # We should be stopped again due to the breakpoint.61 # The stop reason of the thread should be breakpoint.62 self.expect(63 "thread list",64 STOPPED_DUE_TO_BREAKPOINT,65 substrs=["stopped", "stop reason = breakpoint"],66 )67 68 # Now let's set a write-type watchpoint pointed to by 'g_char_ptr'.69 self.expect(70 "watchpoint set expression -w write -s 1 -- g_char_ptr",71 WATCHPOINT_CREATED,72 substrs=["Watchpoint created", "size = 1", "type = w"],73 )74 # Get a hold of the watchpoint id just created, it is used later on to75 # match the watchpoint id which is expected to be fired.76 match = re.match(77 "Watchpoint created: Watchpoint (.*):", self.res.GetOutput().splitlines()[0]78 )79 if match:80 expected_wp_id = int(match.group(1), 0)81 else:82 self.fail("Grokking watchpoint id faailed!")83 84 self.runCmd("expr unsigned val = *g_char_ptr; val")85 self.expect(self.res.GetOutput().splitlines()[0], exe=False, endstr=" = 0")86 87 self.runCmd("watchpoint set expression -w write -s 4 -- &threads[0]")88 89 # Use the '-v' option to do verbose listing of the watchpoint.90 # The hit count should be 0 initially.91 self.expect("watchpoint list -v", substrs=["hit_count = 0"])92 93 self.runCmd("process continue")94 95 # We should be stopped again due to the watchpoint (write type), but96 # only once. The stop reason of the thread should be watchpoint.97 self.expect(98 "thread list",99 STOPPED_DUE_TO_WATCHPOINT,100 substrs=["stopped", "stop reason = watchpoint %d" % expected_wp_id],101 )102 103 # Switch to the thread stopped due to watchpoint and issue some104 # commands.105 self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint)106 self.runCmd("thread backtrace")107 self.expect("frame info", substrs=[self.violating_func])108 109 # Use the '-v' option to do verbose listing of the watchpoint.110 # The hit count should now be the same as the number of threads that111 # stopped on a watchpoint.112 threads = lldbutil.get_stopped_threads(113 self.process(), lldb.eStopReasonWatchpoint114 )115 116 if not self.affected_by_radar_93863107():117 self.expect("watchpoint list -v", substrs=["hit_count = %d" % len(threads)])118 119 self.runCmd("thread backtrace all")120