Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions lldb/include/lldb/Target/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,21 +385,22 @@ class Thread : public std::enable_shared_from_this<Thread>,
virtual void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) {}

/// When a thread stops at an enabled BreakpointSite that has not executed,
/// the Process plugin should call SetThreadStoppedAtUnexecutedBP(pc).
/// the Process plugin should call DetectThreadStoppedAtUnexecutedBP().
/// If that BreakpointSite was actually triggered (the instruction was
/// executed, for a software breakpoint), regardless of whether the
/// breakpoint is valid for this thread, SetThreadHitBreakpointSite()
/// should be called to record that fact.
///
/// Depending on the structure of the Process plugin, it may be easiest
/// to call SetThreadStoppedAtUnexecutedBP(pc) unconditionally when at
/// to call DetectThreadStoppedAtUnexecutedBP() unconditionally when at
/// a BreakpointSite, and later when it is known that it was triggered,
/// SetThreadHitBreakpointSite() can be called. These two methods
/// overwrite the same piece of state in the Thread, the last one
/// called on a Thread wins.
void SetThreadStoppedAtUnexecutedBP(lldb::addr_t pc) {
m_stopped_at_unexecuted_bp = pc;
}
///
/// Returns the BreakpointSite this thread is stopped at, if any.
lldb::BreakpointSiteSP DetectThreadStoppedAtUnexecutedBP();

void SetThreadHitBreakpointSite() {
m_stopped_at_unexecuted_bp = LLDB_INVALID_ADDRESS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -591,11 +591,7 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
// breakpoint at 0x100.
// The fact that the pc may be off by one at this point
// (for an x86 KDP breakpoint hit) is not a problem.
addr_t pc = reg_ctx_sp->GetPC();
BreakpointSiteSP bp_site_sp =
process_sp->GetBreakpointSiteList().FindByAddress(pc);
if (bp_site_sp && bp_site_sp->IsEnabled())
thread.SetThreadStoppedAtUnexecutedBP(pc);
BreakpointSiteSP bp_site_sp = thread.DetectThreadStoppedAtUnexecutedBP();

switch (exc_type) {
case 1: // EXC_BAD_ACCESS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1706,11 +1706,8 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
if (!thread_sp->StopInfoIsUpToDate()) {
thread_sp->SetStopInfo(StopInfoSP());

addr_t pc = thread_sp->GetRegisterContext()->GetPC();
BreakpointSiteSP bp_site_sp =
thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
if (bp_site_sp && bp_site_sp->IsEnabled())
thread_sp->SetThreadStoppedAtUnexecutedBP(pc);
thread_sp->DetectThreadStoppedAtUnexecutedBP();

if (exc_type != 0) {
// For thread plan async interrupt, creating stop info on the
Expand Down
11 changes: 1 addition & 10 deletions lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,7 @@ bool ScriptedThread::CalculateStopInfo() {
LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
LLDBLog::Thread);

// If we're at a BreakpointSite, mark that we stopped there and
// need to hit the breakpoint when we resume. This will be cleared
// if we CreateStopReasonWithBreakpointSiteID.
if (RegisterContextSP reg_ctx_sp = GetRegisterContext()) {
addr_t pc = reg_ctx_sp->GetPC();
if (BreakpointSiteSP bp_site_sp =
GetProcess()->GetBreakpointSiteList().FindByAddress(pc))
if (bp_site_sp->IsEnabled())
SetThreadStoppedAtUnexecutedBP(pc);
}
DetectThreadStoppedAtUnexecutedBP();

lldb::StopInfoSP stop_info_sp;
lldb::StopReason stop_reason_type;
Expand Down
13 changes: 13 additions & 0 deletions lldb/source/Target/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2108,3 +2108,16 @@ lldb::ValueObjectSP Thread::GetSiginfoValue() {
process_sp->GetByteOrder(), arch.GetAddressByteSize()};
return ValueObjectConstResult::Create(&target, type, ConstString("__lldb_siginfo"), data_extractor);
}

BreakpointSiteSP Thread::DetectThreadStoppedAtUnexecutedBP() {
if (RegisterContextSP reg_ctx_sp = GetRegisterContext()) {
addr_t pc = reg_ctx_sp->GetPC();
BreakpointSiteSP bp_site_sp =
GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
if (bp_site_sp && bp_site_sp->IsEnabled()) {
m_stopped_at_unexecuted_bp = pc;
return bp_site_sp;
}
}
return nullptr;
}