2 Test lldb watchpoint that uses '-s size' to watch a pointed location with size.
8 from lldbsuite
.test
.decorators
import *
9 from lldbsuite
.test
.lldbtest
import *
10 from lldbsuite
.test
import lldbutil
13 class HelloWatchLocationTestCase(TestBase
):
14 NO_DEBUG_INFO_TESTCASE
= True
17 # Call super's setUp().
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 test
27 self
.exe_name
= self
.testMethodName
28 self
.d
= {"CXX_SOURCES": self
.source
, "EXE": self
.exe_name
}
30 # on arm64 targets, lldb has incorrect hit-count / ignore-counts
31 # for watchpoints when they are hit with multiple threads at
32 # the same time. Tracked as llvm.org/pr49433
33 # or rdar://93863107 inside Apple.
34 def affected_by_radar_93863107(self
):
36 self
.getArchitecture() in ["arm64", "arm64e"]
37 ) and self
.platformIsDarwin()
39 # Most of the MIPS boards provide only one H/W watchpoints, and S/W
40 # watchpoints are not supported yet
41 @expectedFailureAll(triple
=re
.compile("^mips"))
42 # SystemZ and PowerPC also currently supports only one H/W watchpoint
43 @expectedFailureAll(archs
=["powerpc64le", "s390x"])
44 @skipIfWindows # This test is flaky on Windows
45 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
)
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
=False
58 self
.runCmd("run", RUN_SUCCEEDED
)
60 # We should be stopped again due to the breakpoint.
61 # The stop reason of the thread should be breakpoint.
64 STOPPED_DUE_TO_BREAKPOINT
,
65 substrs
=["stopped", "stop reason = breakpoint"],
68 # Now let's set a write-type watchpoint pointed to by 'g_char_ptr'.
70 "watchpoint set expression -w write -s 1 -- g_char_ptr",
72 substrs
=["Watchpoint created", "size = 1", "type = w"],
74 # Get a hold of the watchpoint id just created, it is used later on to
75 # match the watchpoint id which is expected to be fired.
77 "Watchpoint created: Watchpoint (.*):", self
.res
.GetOutput().splitlines()[0]
80 expected_wp_id
= int(match
.group(1), 0)
82 self
.fail("Grokking watchpoint id faailed!")
84 self
.runCmd("expr unsigned val = *g_char_ptr; val")
85 self
.expect(self
.res
.GetOutput().splitlines()[0], exe
=False, endstr
=" = 0")
87 self
.runCmd("watchpoint set expression -w write -s 4 -- &threads[0]")
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"])
93 self
.runCmd("process continue")
95 # We should be stopped again due to the watchpoint (write type), but
96 # only once. The stop reason of the thread should be watchpoint.
99 STOPPED_DUE_TO_WATCHPOINT
,
100 substrs
=["stopped", "stop reason = watchpoint %d" % expected_wp_id
],
103 # Switch to the thread stopped due to watchpoint and issue some
105 self
.switch_to_thread_with_stop_reason(lldb
.eStopReasonWatchpoint
)
106 self
.runCmd("thread backtrace")
107 self
.expect("frame info", substrs
=[self
.violating_func
])
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 that
111 # stopped on a watchpoint.
112 threads
= lldbutil
.get_stopped_threads(
113 self
.process(), lldb
.eStopReasonWatchpoint
116 if not self
.affected_by_radar_93863107():
117 self
.expect("watchpoint list -v", substrs
=["hit_count = %d" % len(threads
)])
119 self
.runCmd("thread backtrace all")