Files
clang-p2996/lldb/test/API/commands/watchpoints/watchpoint_set_command/TestWatchLocationWithWatchSet.py
Jason Molenda 6d6feaf7e3 [lldb][NFC] update API tests which skip/expect-fail arm
The architectures provided to skipIf / expectedFail are regular
expressions (v. _match_decorator_property() in decorators.py
so on Darwin systems "arm64" would match the skips for "arm" (32-bit
Linux).  Update these to "arm$" to prevent this, and also update
three tests (TestBuiltinFormats.py, TestCrossDSOTailCalls.py,
TestCrossObjectTailCalls.py) that were skipped for arm64 via this
behavior, and need to be skipped or they will fail.

This was moviated by the new TestDynamicValue.py test which has
an expected-fail for arm, but the test was passing on arm64 Darwin
resulting in failure for the CIs.
2025-05-27 18:41:16 -07:00

116 lines
4.4 KiB
Python

"""
Test lldb watchpoint that uses 'watchpoint set -w write -s size' to watch a pointed location with size.
"""
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class WatchLocationUsingWatchpointSetTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
# on arm64 targets, lldb has incorrect hit-count / ignore-counts
# for watchpoints when they are hit with multiple threads at
# the same time. Tracked as llvm.org/pr49433
# or rdar://93863107 inside Apple.
def affected_by_radar_93863107(self):
return (
self.getArchitecture() in ["arm64", "arm64e"]
) and self.platformIsDarwin()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Our simple source filename.
self.source = "main.cpp"
# Find the line number to break inside main().
self.line = line_number(self.source, "// Set break point at this line.")
# This is for verifying that watch location works.
self.violating_func = "do_bad_thing_with_location"
# Build dictionary to have unique executable names for each test
# method.
@skipIf(oslist=["linux"], archs=["aarch64", "arm$"], bugnumber="llvm.org/pr26031")
@skipIfWindows # This test is flaky on Windows
def test_watchlocation_using_watchpoint_set(self):
"""Test watching a location with 'watchpoint set expression -w write -s size' option."""
self.build()
self.setTearDownCleanup()
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
# Add a breakpoint to set a watchpoint when stopped on the breakpoint.
lldbutil.run_break_set_by_file_and_line(
self, None, self.line, num_expected_locations=1
)
# Run the program.
self.runCmd("run", RUN_SUCCEEDED)
# We should be stopped again due to the breakpoint.
# The stop reason of the thread should be breakpoint.
self.expect(
"thread list",
STOPPED_DUE_TO_BREAKPOINT,
substrs=["stopped", "stop reason = breakpoint"],
)
# Now let's set a write-type watchpoint pointed to by 'g_char_ptr' and
# with offset as 7.
# The main.cpp, by design, misbehaves by not following the agreed upon
# protocol of only accessing the allowable index range of [0, 6].
self.expect(
"watchpoint set expression -w write -s 1 -- g_char_ptr + 7",
WATCHPOINT_CREATED,
substrs=["Watchpoint created", "size = 1", "type = w"],
)
self.runCmd("expr unsigned val = g_char_ptr[7]; val")
self.expect(self.res.GetOutput().splitlines()[0], exe=False, endstr=" = 0")
# Use the '-v' option to do verbose listing of the watchpoint.
# The hit count should be 0 initially.
self.expect("watchpoint list -v", substrs=["hit_count = 0"])
# Check the underlying SBWatchpoint.
watchpoint = target.GetWatchpointAtIndex(0)
self.assertEqual(watchpoint.GetWatchSize(), 1)
self.assertEqual(watchpoint.GetHitCount(), 0)
self.assertEqual(watchpoint.GetWatchSpec(), "g_char_ptr + 7")
self.runCmd("process continue")
# We should be stopped again due to the watchpoint (write type), but
# only once. The stop reason of the thread should be watchpoint.
self.expect(
"thread list",
STOPPED_DUE_TO_WATCHPOINT,
substrs=[
"stopped",
self.violating_func,
"stop reason = watchpoint",
],
)
# Switch to the thread stopped due to watchpoint and issue some
# commands.
self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint)
self.runCmd("thread backtrace")
self.runCmd("expr unsigned val = g_char_ptr[7]; val")
self.expect(self.res.GetOutput().splitlines()[0], exe=False, endstr=" = 99")
# Use the '-v' option to do verbose listing of the watchpoint.
# The hit count should now be the same as the number of threads that
# stopped on a watchpoint.
threads = lldbutil.get_stopped_threads(
self.process(), lldb.eStopReasonWatchpoint
)
if not self.affected_by_radar_93863107():
self.expect("watchpoint list -v", substrs=["hit_count = %d" % len(threads)])
self.runCmd("thread backtrace all")