Skip to content

Commit a9fba1a

Browse files
committed
[lldb] Add pc check for thread-step-by-bp algorithms (llvm#108504)
lldb-server built with NativeProcessLinux.cpp and NativeProcessFreeBSD.cpp can use breakpoints to implement instruction stepping on cores where there is no native instruction-step primitive. Currently these set a breakpoint, continue, and if we hit the breakpoint with the original thread, set the stop reason to be "trace". I am wrapping up a change to lldb's breakpoint algorithm where I change its current behavior of "if a thread stops at a breakpoint site, we set the thread's stop reason to breakpoint-hit, even if the breakpoint hasn't been executed" + "when resuming any thread at a breakpoint site, instruction-step past the breakpoint before resuming" to a behavior of "when a thread executes a breakpoint, set the stop reason to breakpoint-hit" + "when a thread has hit a breakpoint, when the thread resumes, we silently step past the breakpoint and then resume the thread". For these lldb-server targets doing breakpoint stepping, this means that if we are sitting on a breakpoint that has not yet executed, and instruction-step the thread, we will execute the breakpoint instruction at $pc (instead of $next-pc where it meant to go), and stop again -- at the same pc value. Then we will rewrite the stop reason to 'trace'. The higher level logic will see that we haven't hit the breakpoint instruction again, so it will try to instruction step again, hitting the breakpoint again forever. To fix this, I'm checking that the thread matches the one we are instruction-stepping-by-breakpoint AND that we've stopped at the breakpoint address we are stepping to. Only in that case will the stop reason be rewritten to "trace" hiding the implementation detail that the step was done by breakpoints. (cherry picked from commit 213c59d)
1 parent 384ec39 commit a9fba1a

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,12 @@ void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
319319
info.pl_siginfo.si_addr);
320320

321321
if (thread) {
322+
auto &regctx = static_cast<NativeRegisterContextFreeBSD &>(
323+
thread->GetRegisterContext());
322324
auto thread_info =
323325
m_threads_stepping_with_breakpoint.find(thread->GetID());
324-
if (thread_info != m_threads_stepping_with_breakpoint.end()) {
326+
if (thread_info != m_threads_stepping_with_breakpoint.end() &&
327+
threads_info->second == regctx.GetPC()) {
325328
thread->SetStoppedByTrace();
326329
Status brkpt_error = RemoveBreakpoint(thread_info->second);
327330
if (brkpt_error.Fail())

lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,11 @@ void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) {
829829
thread.SetStoppedByBreakpoint();
830830
FixupBreakpointPCAsNeeded(thread);
831831

832-
if (m_threads_stepping_with_breakpoint.find(thread.GetID()) !=
833-
m_threads_stepping_with_breakpoint.end())
832+
NativeRegisterContextLinux &reg_ctx = thread.GetRegisterContext();
833+
auto stepping_with_bp_it =
834+
m_threads_stepping_with_breakpoint.find(thread.GetID());
835+
if (stepping_with_bp_it != m_threads_stepping_with_breakpoint.end() &&
836+
stepping_with_bp_it->second == reg_ctx.GetPC())
834837
thread.SetStoppedByTrace();
835838

836839
StopRunningThreads(thread.GetID());

0 commit comments

Comments
 (0)