2 Test lldb watchpoint that uses 'watchpoint set -w write -s size' to watch a pointed location with size.
7 from lldbsuite
.test
.decorators
import *
8 from lldbsuite
.test
.lldbtest
import *
9 from lldbsuite
.test
import lldbutil
12 class WatchLocationUsingWatchpointSetTestCase(TestBase
):
13 NO_DEBUG_INFO_TESTCASE
= True
15 # on arm64 targets, lldb has incorrect hit-count / ignore-counts
16 # for watchpoints when they are hit with multiple threads at
17 # the same time. Tracked as llvm.org/pr49433
18 # or rdar://93863107 inside Apple.
19 def affected_by_radar_93863107(self
):
21 self
.getArchitecture() in ["arm64", "arm64e"]
22 ) and self
.platformIsDarwin()
25 # Call super's setUp().
27 # Our simple source filename.
28 self
.source
= "main.cpp"
29 # Find the line number to break inside main().
30 self
.line
= line_number(self
.source
, "// Set break point at this line.")
31 # This is for verifying that watch location works.
32 self
.violating_func
= "do_bad_thing_with_location"
33 # Build dictionary to have unique executable names for each test
36 @skipIf(oslist
=["linux"], archs
=["aarch64", "arm"], bugnumber
="llvm.org/pr26031")
37 @skipIfWindows # This test is flaky on Windows
38 def test_watchlocation_using_watchpoint_set(self
):
39 """Test watching a location with 'watchpoint set expression -w write -s size' option."""
41 self
.setTearDownCleanup()
43 exe
= self
.getBuildArtifact("a.out")
44 target
= self
.dbg
.CreateTarget(exe
)
46 # Add a breakpoint to set a watchpoint when stopped on the breakpoint.
47 lldbutil
.run_break_set_by_file_and_line(
48 self
, None, self
.line
, num_expected_locations
=1
52 self
.runCmd("run", RUN_SUCCEEDED
)
54 # We should be stopped again due to the breakpoint.
55 # The stop reason of the thread should be breakpoint.
58 STOPPED_DUE_TO_BREAKPOINT
,
59 substrs
=["stopped", "stop reason = breakpoint"],
62 # Now let's set a write-type watchpoint pointed to by 'g_char_ptr' and
64 # The main.cpp, by design, misbehaves by not following the agreed upon
65 # protocol of only accessing the allowable index range of [0, 6].
67 "watchpoint set expression -w write -s 1 -- g_char_ptr + 7",
69 substrs
=["Watchpoint created", "size = 1", "type = w"],
71 self
.runCmd("expr unsigned val = g_char_ptr[7]; val")
72 self
.expect(self
.res
.GetOutput().splitlines()[0], exe
=False, endstr
=" = 0")
74 # Use the '-v' option to do verbose listing of the watchpoint.
75 # The hit count should be 0 initially.
76 self
.expect("watchpoint list -v", substrs
=["hit_count = 0"])
78 # Check the underlying SBWatchpoint.
79 watchpoint
= target
.GetWatchpointAtIndex(0)
80 self
.assertEqual(watchpoint
.GetWatchSize(), 1)
81 self
.assertEqual(watchpoint
.GetHitCount(), 0)
82 self
.assertEqual(watchpoint
.GetWatchSpec(), "g_char_ptr + 7")
84 self
.runCmd("process continue")
86 # We should be stopped again due to the watchpoint (write type), but
87 # only once. The stop reason of the thread should be watchpoint.
90 STOPPED_DUE_TO_WATCHPOINT
,
94 "stop reason = watchpoint",
98 # Switch to the thread stopped due to watchpoint and issue some
100 self
.switch_to_thread_with_stop_reason(lldb
.eStopReasonWatchpoint
)
101 self
.runCmd("thread backtrace")
102 self
.runCmd("expr unsigned val = g_char_ptr[7]; val")
103 self
.expect(self
.res
.GetOutput().splitlines()[0], exe
=False, endstr
=" = 99")
105 # Use the '-v' option to do verbose listing of the watchpoint.
106 # The hit count should now be the same as the number of threads that
107 # stopped on a watchpoint.
108 threads
= lldbutil
.get_stopped_threads(
109 self
.process(), lldb
.eStopReasonWatchpoint
112 if not self
.affected_by_radar_93863107():
113 self
.expect("watchpoint list -v", substrs
=["hit_count = %d" % len(threads
)])
115 self
.runCmd("thread backtrace all")