Skip to content

[lldb] Change breakpoint interfaces for error handling #146972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
14 changes: 3 additions & 11 deletions lldb/include/lldb/Breakpoint/BreakpointLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class BreakpointLocation
// The next section deals with various breakpoint options.

/// If \a enabled is \b true, enable the breakpoint, if \b false disable it.
bool SetEnabled(bool enabled);
llvm::Error SetEnabled(bool enabled);

/// Check the Enable/Disable state.
///
Expand Down Expand Up @@ -163,19 +163,11 @@ class BreakpointLocation
// The next section deals with this location's breakpoint sites.

/// Try to resolve the breakpoint site for this location.
///
/// \return
/// \b true if we were successful at setting a breakpoint site,
/// \b false otherwise.
bool ResolveBreakpointSite();
llvm::Error ResolveBreakpointSite();

/// Clear this breakpoint location's breakpoint site - for instance when
/// disabling the breakpoint.
///
/// \return
/// \b true if there was a breakpoint site to be cleared, \b false
/// otherwise.
bool ClearBreakpointSite();
llvm::Error ClearBreakpointSite();

/// Return whether this breakpoint location has a breakpoint site. \return
/// \b true if there was a breakpoint site for this breakpoint
Expand Down
16 changes: 13 additions & 3 deletions lldb/source/Breakpoint/Breakpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ llvm::Error Breakpoint::SetIsHardware(bool is_hardware) {
if (is_hardware == m_hardware)
return llvm::Error::success();

Log *log = GetLog(LLDBLog::Breakpoints);

// Disable all non-hardware breakpoint locations.
std::vector<BreakpointLocationSP> locations;
for (BreakpointLocationSP location_sp : m_locations.BreakpointLocations()) {
Expand All @@ -268,7 +270,9 @@ llvm::Error Breakpoint::SetIsHardware(bool is_hardware) {
continue;

locations.push_back(location_sp);
location_sp->SetEnabled(false);
if (llvm::Error error = location_sp->SetEnabled(false))
LLDB_LOG_ERROR(log, std::move(error),
"Failed to disable breakpoint location: {0}");
}

// Toggle the hardware mode.
Expand All @@ -277,8 +281,11 @@ llvm::Error Breakpoint::SetIsHardware(bool is_hardware) {
// Re-enable all breakpoint locations.
size_t num_failures = 0;
for (BreakpointLocationSP location_sp : locations) {
if (!location_sp->SetEnabled(true))
if (llvm::Error error = location_sp->SetEnabled(true)) {
LLDB_LOG_ERROR(log, std::move(error),
"Failed to re-enable breakpoint location: {0}");
num_failures++;
}
}

if (num_failures != 0)
Expand Down Expand Up @@ -613,7 +620,10 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
// Remove this breakpoint since the shared library is unloaded, but
// keep the breakpoint location around so we always get complete
// hit count and breakpoint lifetime info
break_loc_sp->ClearBreakpointSite();
if (llvm::Error error = break_loc_sp->ClearBreakpointSite())
LLDB_LOG_ERROR(log, std::move(error),
"Failed to clear breakpoint locations on library "
"unload: {0}");
if (removed_locations_event) {
removed_locations_event->GetBreakpointLocationCollection().Add(
break_loc_sp);
Expand Down
64 changes: 33 additions & 31 deletions lldb/source/Breakpoint/BreakpointLocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
SetThreadIDInternal(tid);
}

BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
BreakpointLocation::~BreakpointLocation() {
llvm::consumeError(ClearBreakpointSite());
}

lldb::addr_t BreakpointLocation::GetLoadAddress() const {
return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
Expand All @@ -72,13 +74,12 @@ bool BreakpointLocation::IsEnabled() const {
return true;
}

bool BreakpointLocation::SetEnabled(bool enabled) {
llvm::Error BreakpointLocation::SetEnabled(bool enabled) {
GetLocationOptions().SetEnabled(enabled);
const bool success =
enabled ? ResolveBreakpointSite() : ClearBreakpointSite();
llvm::Error error = enabled ? ResolveBreakpointSite() : ClearBreakpointSite();
SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
: eBreakpointEventTypeDisabled);
return success;
return error;
}

bool BreakpointLocation::IsAutoContinue() const {
Expand Down Expand Up @@ -422,25 +423,27 @@ lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
return m_bp_site_sp;
}

bool BreakpointLocation::ResolveBreakpointSite() {
llvm::Error BreakpointLocation::ResolveBreakpointSite() {
if (m_bp_site_sp)
return true;
return llvm::Error::success();

Process *process = m_owner.GetTarget().GetProcessSP().get();
if (process == nullptr)
return false;
return llvm::createStringError("no process");

lldb::break_id_t new_id =
process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());

if (new_id == LLDB_INVALID_BREAK_ID) {
LLDB_LOGF(GetLog(LLDBLog::Breakpoints),
"Failed to add breakpoint site at 0x%" PRIx64 "(resolved=%s)",
m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
IsResolved() ? "yes" : "no");
}
if (new_id == LLDB_INVALID_BREAK_ID)
return llvm::createStringError(
llvm::formatv("Failed to add breakpoint site at {0:x}",
m_address.GetOpcodeLoadAddress(&m_owner.GetTarget())));

if (!IsResolved())
return llvm::createStringError(
"breakpoint site created but location is still unresolved");

return IsResolved();
return llvm::Error::success();
}

bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
Expand All @@ -449,22 +452,21 @@ bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
return true;
}

bool BreakpointLocation::ClearBreakpointSite() {
if (m_bp_site_sp.get()) {
ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
// If the process exists, get it to remove the owner, it will remove the
// physical implementation of the breakpoint as well if there are no more
// owners. Otherwise just remove this owner.
if (process_sp)
process_sp->RemoveConstituentFromBreakpointSite(GetBreakpoint().GetID(),
GetID(), m_bp_site_sp);
else
m_bp_site_sp->RemoveConstituent(GetBreakpoint().GetID(), GetID());

m_bp_site_sp.reset();
return true;
}
return false;
llvm::Error BreakpointLocation::ClearBreakpointSite() {
if (!m_bp_site_sp)
return llvm::createStringError("no breakpoint site to clear");

// If the process exists, get it to remove the owner, it will remove the
// physical implementation of the breakpoint as well if there are no more
// owners. Otherwise just remove this owner.
if (ProcessSP process_sp = m_owner.GetTarget().GetProcessSP())
process_sp->RemoveConstituentFromBreakpointSite(GetBreakpoint().GetID(),
GetID(), m_bp_site_sp);
else
m_bp_site_sp->RemoveConstituent(GetBreakpoint().GetID(), GetID());

m_bp_site_sp.reset();
return llvm::Error::success();
}

void BreakpointLocation::GetDescription(Stream *s,
Expand Down
22 changes: 16 additions & 6 deletions lldb/source/Breakpoint/BreakpointLocationList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

using namespace lldb;
using namespace lldb_private;
Expand Down Expand Up @@ -151,17 +153,24 @@ const BreakpointLocationSP BreakpointLocationList::GetByIndex(size_t i) const {
void BreakpointLocationList::ClearAllBreakpointSites() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
(*pos)->ClearBreakpointSite();
Log *log = GetLog(LLDBLog::Breakpoints);

for (pos = m_locations.begin(); pos != end; ++pos) {
if (llvm::Error error = (*pos)->ClearBreakpointSite())
LLDB_LOG_ERROR(log, std::move(error), "{0}");
}
}

void BreakpointLocationList::ResolveAllBreakpointSites() {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
collection::iterator pos, end = m_locations.end();
Log *log = GetLog(LLDBLog::Breakpoints);

for (pos = m_locations.begin(); pos != end; ++pos) {
if ((*pos)->IsEnabled())
(*pos)->ResolveBreakpointSite();
if ((*pos)->IsEnabled()) {
if (llvm::Error error = (*pos)->ResolveBreakpointSite())
LLDB_LOG_ERROR(log, std::move(error), "{0}");
}
}
}

Expand Down Expand Up @@ -212,7 +221,8 @@ BreakpointLocationSP BreakpointLocationList::AddLocation(
if (!bp_loc_sp) {
bp_loc_sp = Create(addr, resolve_indirect_symbols);
if (bp_loc_sp) {
bp_loc_sp->ResolveBreakpointSite();
if (llvm::Error error = bp_loc_sp->ResolveBreakpointSite())
LLDB_LOG_ERROR(GetLog(LLDBLog::Breakpoints), std::move(error), "{0}");

if (new_location)
*new_location = true;
Expand All @@ -234,7 +244,7 @@ void BreakpointLocationList::SwapLocation(
to_location_sp->SwapLocation(from_location_sp);
RemoveLocation(from_location_sp);
m_address_to_location[to_location_sp->GetAddress()] = to_location_sp;
to_location_sp->ResolveBreakpointSite();
llvm::consumeError(to_location_sp->ResolveBreakpointSite());
}

bool BreakpointLocationList::RemoveLocation(
Expand Down
5 changes: 2 additions & 3 deletions lldb/source/Breakpoint/BreakpointSite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ BreakpointSite::BreakpointSite(const BreakpointLocationSP &constituent,
BreakpointSite::~BreakpointSite() {
BreakpointLocationSP bp_loc_sp;
const size_t constituent_count = m_constituents.GetSize();
for (size_t i = 0; i < constituent_count; i++) {
m_constituents.GetByIndex(i)->ClearBreakpointSite();
}
for (size_t i = 0; i < constituent_count; i++)
llvm::consumeError(m_constituents.GetByIndex(i)->ClearBreakpointSite());
}

break_id_t BreakpointSite::GetNextID() {
Expand Down
Loading