Skip to content

Commit 0123db6

Browse files
authored
Merge pull request #9315 from jasonmolenda/cp/136247381-dont-invalid-register-context-unnecessarily
[lldb] Don't invalid register context after setting thread pc's (llvm#109499)
2 parents 0c53583 + 081f43b commit 0123db6

File tree

5 files changed

+165
-1
lines changed

5 files changed

+165
-1
lines changed

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,6 @@ bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) {
15971597
// If we have "jstopinfo" then we have stop descriptions for all threads
15981598
// that have stop reasons, and if there is no entry for a thread, then it
15991599
// has no stop reason.
1600-
thread->GetRegisterContext()->InvalidateIfNeeded(true);
16011600
if (!GetThreadStopInfoFromJSON(thread, m_jstopinfo_sp)) {
16021601
// If a thread is stopped at a breakpoint site, set that as the stop
16031602
// reason even if it hasn't executed the breakpoint instruction yet.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CXX_SOURCES := main.cpp
2+
3+
.PHONY: build-libfoo
4+
all: build-libfoo a.out
5+
6+
include Makefile.rules
7+
8+
build-libfoo: foo.c
9+
$(MAKE) -f $(MAKEFILE_RULES) \
10+
DYLIB_C_SOURCES=foo.c DYLIB_NAME=foo DYLIB_ONLY=YES
11+
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
"""Test that the expedited thread pc values are not re-fetched by lldb."""
2+
3+
import subprocess
4+
import lldb
5+
from lldbsuite.test.decorators import *
6+
from lldbsuite.test.lldbtest import *
7+
from lldbsuite.test import lldbutil
8+
9+
file_index = 0
10+
11+
12+
class TestExpeditedThreadPCs(TestBase):
13+
NO_DEBUG_INFO_TESTCASE = True
14+
15+
@skipUnlessDarwin
16+
def test_expedited_thread_pcs(self):
17+
TestBase.setUp(self)
18+
19+
global file_index
20+
++file_index
21+
logfile = os.path.join(
22+
self.getBuildDir(),
23+
"packet-log-" + self.getArchitecture() + "-" + str(file_index) + ".txt",
24+
)
25+
self.runCmd("log enable -f %s gdb-remote packets" % (logfile))
26+
27+
def cleanup():
28+
self.runCmd("log disable gdb-remote packets")
29+
if os.path.exists(logfile):
30+
os.unlink(logfile)
31+
32+
self.addTearDownHook(cleanup)
33+
34+
self.source = "main.cpp"
35+
self.build()
36+
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
37+
self, "break here", lldb.SBFileSpec(self.source, False)
38+
)
39+
40+
# verify that libfoo.dylib hasn't loaded yet
41+
for m in target.modules:
42+
self.assertNotEqual(m.GetFileSpec().GetFilename(), "libfoo.dylib")
43+
44+
thread.StepInto()
45+
thread.StepInto()
46+
47+
thread.StepInto()
48+
thread.StepInto()
49+
thread.StepInto()
50+
51+
# verify that libfoo.dylib has loaded
52+
for m in target.modules:
53+
if m.GetFileSpec().GetFilename() == "libfoo.dylib":
54+
found_libfoo = True
55+
self.assertTrue(found_libfoo)
56+
57+
thread.StepInto()
58+
thread.StepInto()
59+
thread.StepOver()
60+
thread.StepOver()
61+
thread.StepOver()
62+
thread.StepOver()
63+
thread.StepOver()
64+
thread.StepOver()
65+
thread.StepOver()
66+
thread.StepOver()
67+
thread.StepOver()
68+
thread.StepOver()
69+
70+
process.Kill()
71+
72+
# Confirm that we never fetched the pc for any threads during
73+
# this debug session.
74+
if os.path.exists(logfile):
75+
f = open(logfile)
76+
lines = f.readlines()
77+
num_errors = 0
78+
for line in lines:
79+
arch = self.getArchitecture()
80+
if arch == "arm64" or arch == "arm64_32":
81+
# <reg name="pc" regnum="32" offset="256" bitsize="64" group="general" group_id="1" ehframe_regnum="32" dwarf_regnum="32" generic="pc"/>
82+
# A fetch of $pc on arm64 looks like
83+
# < 22> send packet: $p20;thread:91698e;#70
84+
self.assertNotIn("$p20;thread", line)
85+
else:
86+
# <reg name="rip" regnum="16" offset="128" bitsize="64" group="general" altname="pc" group_id="1" ehframe_regnum="16" dwarf_regnum="16" generic="pc"/>
87+
# A fetch of $pc on x86_64 looks like
88+
# < 22> send packet: $p10;thread:91889c;#6f
89+
self.assertNotIn("$p10;thread", line)
90+
91+
f.close()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int foo() { return 5; }
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <dlfcn.h>
2+
#include <stdio.h>
3+
#include <thread>
4+
#include <unistd.h>
5+
6+
void f1() {
7+
while (1)
8+
sleep(1);
9+
}
10+
void f2() {
11+
while (1)
12+
sleep(1);
13+
}
14+
void f3() {
15+
while (1)
16+
sleep(1);
17+
}
18+
19+
int main() {
20+
std::thread t1{f1};
21+
std::thread t2{f2};
22+
std::thread t3{f3};
23+
24+
puts("break here");
25+
26+
void *handle = dlopen("libfoo.dylib", RTLD_LAZY);
27+
int (*foo_ptr)() = (int (*)())dlsym(handle, "foo");
28+
int c = foo_ptr();
29+
30+
// clang-format off
31+
// multiple function calls on a single source line so 'step'
32+
// and 'next' need to do multiple steps of work.
33+
puts("1"); puts("2"); puts("3"); puts("4"); puts("5");
34+
puts("6"); puts("7"); puts("8"); puts("9"); puts("10");
35+
puts("11"); puts("12"); puts("13"); puts("14"); puts("15");
36+
puts("16"); puts("17"); puts("18"); puts("19"); puts("20");
37+
puts("21"); puts("22"); puts("23"); puts("24"); puts("24");
38+
// clang-format on
39+
puts("one");
40+
puts("two");
41+
puts("three");
42+
puts("four");
43+
puts("five");
44+
puts("six");
45+
puts("seven");
46+
puts("eight");
47+
puts("nine");
48+
puts("ten");
49+
c++;
50+
c++;
51+
c++;
52+
c++;
53+
c++;
54+
c++;
55+
c++;
56+
c++;
57+
c++;
58+
c++;
59+
c++;
60+
c++;
61+
return c;
62+
}

0 commit comments

Comments
 (0)