Skip to content

Commit d193a58

Browse files
authored
[lldb] Change breakpoint interfaces for error handling (#146972)
This RP changes some Breakpoint-related interfaces to return errors. On its own these improvements are small, but they encourage better error handling going forward. There are a bunch of other candidates, but these were the functions that I touched while working on #146602.
1 parent 0d2b47a commit d193a58

File tree

9 files changed

+104
-70
lines changed

9 files changed

+104
-70
lines changed

lldb/include/lldb/Breakpoint/BreakpointLocation.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class BreakpointLocation
6969
// The next section deals with various breakpoint options.
7070

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

7474
/// Check the Enable/Disable state.
7575
///
@@ -163,19 +163,11 @@ class BreakpointLocation
163163
// The next section deals with this location's breakpoint sites.
164164

165165
/// Try to resolve the breakpoint site for this location.
166-
///
167-
/// \return
168-
/// \b true if we were successful at setting a breakpoint site,
169-
/// \b false otherwise.
170-
bool ResolveBreakpointSite();
166+
llvm::Error ResolveBreakpointSite();
171167

172168
/// Clear this breakpoint location's breakpoint site - for instance when
173169
/// disabling the breakpoint.
174-
///
175-
/// \return
176-
/// \b true if there was a breakpoint site to be cleared, \b false
177-
/// otherwise.
178-
bool ClearBreakpointSite();
170+
llvm::Error ClearBreakpointSite();
179171

180172
/// Return whether this breakpoint location has a breakpoint site. \return
181173
/// \b true if there was a breakpoint site for this breakpoint

lldb/source/API/SBBreakpointLocation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void SBBreakpointLocation::SetEnabled(bool enabled) {
102102
if (loc_sp) {
103103
std::lock_guard<std::recursive_mutex> guard(
104104
loc_sp->GetTarget().GetAPIMutex());
105-
loc_sp->SetEnabled(enabled);
105+
llvm::consumeError(loc_sp->SetEnabled(enabled));
106106
}
107107
}
108108

lldb/source/Breakpoint/Breakpoint.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ llvm::Error Breakpoint::SetIsHardware(bool is_hardware) {
255255
if (is_hardware == m_hardware)
256256
return llvm::Error::success();
257257

258+
Log *log = GetLog(LLDBLog::Breakpoints);
259+
258260
// Disable all non-hardware breakpoint locations.
259261
std::vector<BreakpointLocationSP> locations;
260262
for (BreakpointLocationSP location_sp : m_locations.BreakpointLocations()) {
@@ -268,7 +270,9 @@ llvm::Error Breakpoint::SetIsHardware(bool is_hardware) {
268270
continue;
269271

270272
locations.push_back(location_sp);
271-
location_sp->SetEnabled(false);
273+
if (llvm::Error error = location_sp->SetEnabled(false))
274+
LLDB_LOG_ERROR(log, std::move(error),
275+
"Failed to disable breakpoint location: {0}");
272276
}
273277

274278
// Toggle the hardware mode.
@@ -277,8 +281,11 @@ llvm::Error Breakpoint::SetIsHardware(bool is_hardware) {
277281
// Re-enable all breakpoint locations.
278282
size_t num_failures = 0;
279283
for (BreakpointLocationSP location_sp : locations) {
280-
if (!location_sp->SetEnabled(true))
284+
if (llvm::Error error = location_sp->SetEnabled(true)) {
285+
LLDB_LOG_ERROR(log, std::move(error),
286+
"Failed to re-enable breakpoint location: {0}");
281287
num_failures++;
288+
}
282289
}
283290

284291
if (num_failures != 0)
@@ -570,11 +577,11 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
570577
if (!seen)
571578
seen = true;
572579

573-
if (!break_loc_sp->ResolveBreakpointSite()) {
574-
LLDB_LOGF(log,
575-
"Warning: could not set breakpoint site for "
576-
"breakpoint location %d of breakpoint %d.\n",
577-
break_loc_sp->GetID(), GetID());
580+
if (llvm::Error error = break_loc_sp->ResolveBreakpointSite()) {
581+
LLDB_LOG_ERROR(log, std::move(error),
582+
"could not set breakpoint site for "
583+
"breakpoint location {1} of breakpoint {2}: {0}",
584+
break_loc_sp->GetID(), GetID());
578585
}
579586
}
580587
}
@@ -613,7 +620,10 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load,
613620
// Remove this breakpoint since the shared library is unloaded, but
614621
// keep the breakpoint location around so we always get complete
615622
// hit count and breakpoint lifetime info
616-
break_loc_sp->ClearBreakpointSite();
623+
if (llvm::Error error = break_loc_sp->ClearBreakpointSite())
624+
LLDB_LOG_ERROR(log, std::move(error),
625+
"Failed to clear breakpoint locations on library "
626+
"unload: {0}");
617627
if (removed_locations_event) {
618628
removed_locations_event->GetBreakpointLocationCollection().Add(
619629
break_loc_sp);

lldb/source/Breakpoint/BreakpointLocation.cpp

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
4545
SetThreadIDInternal(tid);
4646
}
4747

48-
BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
48+
BreakpointLocation::~BreakpointLocation() {
49+
llvm::consumeError(ClearBreakpointSite());
50+
}
4951

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

75-
bool BreakpointLocation::SetEnabled(bool enabled) {
77+
llvm::Error BreakpointLocation::SetEnabled(bool enabled) {
7678
GetLocationOptions().SetEnabled(enabled);
77-
const bool success =
78-
enabled ? ResolveBreakpointSite() : ClearBreakpointSite();
79+
llvm::Error error = enabled ? ResolveBreakpointSite() : ClearBreakpointSite();
7980
SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
8081
: eBreakpointEventTypeDisabled);
81-
return success;
82+
return error;
8283
}
8384

8485
bool BreakpointLocation::IsAutoContinue() const {
@@ -422,25 +423,27 @@ lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
422423
return m_bp_site_sp;
423424
}
424425

425-
bool BreakpointLocation::ResolveBreakpointSite() {
426+
llvm::Error BreakpointLocation::ResolveBreakpointSite() {
426427
if (m_bp_site_sp)
427-
return true;
428+
return llvm::Error::success();
428429

429430
Process *process = m_owner.GetTarget().GetProcessSP().get();
430431
if (process == nullptr)
431-
return false;
432+
return llvm::createStringError("no process");
432433

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

436-
if (new_id == LLDB_INVALID_BREAK_ID) {
437-
LLDB_LOGF(GetLog(LLDBLog::Breakpoints),
438-
"Failed to add breakpoint site at 0x%" PRIx64 "(resolved=%s)",
439-
m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
440-
IsResolved() ? "yes" : "no");
441-
}
437+
if (new_id == LLDB_INVALID_BREAK_ID)
438+
return llvm::createStringError(
439+
llvm::formatv("Failed to add breakpoint site at {0:x}",
440+
m_address.GetOpcodeLoadAddress(&m_owner.GetTarget())));
441+
442+
if (!IsResolved())
443+
return llvm::createStringError(
444+
"breakpoint site created but location is still unresolved");
442445

443-
return IsResolved();
446+
return llvm::Error::success();
444447
}
445448

446449
bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
@@ -449,22 +452,21 @@ bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
449452
return true;
450453
}
451454

452-
bool BreakpointLocation::ClearBreakpointSite() {
453-
if (m_bp_site_sp.get()) {
454-
ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
455-
// If the process exists, get it to remove the owner, it will remove the
456-
// physical implementation of the breakpoint as well if there are no more
457-
// owners. Otherwise just remove this owner.
458-
if (process_sp)
459-
process_sp->RemoveConstituentFromBreakpointSite(GetBreakpoint().GetID(),
460-
GetID(), m_bp_site_sp);
461-
else
462-
m_bp_site_sp->RemoveConstituent(GetBreakpoint().GetID(), GetID());
463-
464-
m_bp_site_sp.reset();
465-
return true;
466-
}
467-
return false;
455+
llvm::Error BreakpointLocation::ClearBreakpointSite() {
456+
if (!m_bp_site_sp)
457+
return llvm::createStringError("no breakpoint site to clear");
458+
459+
// If the process exists, get it to remove the owner, it will remove the
460+
// physical implementation of the breakpoint as well if there are no more
461+
// owners. Otherwise just remove this owner.
462+
if (ProcessSP process_sp = m_owner.GetTarget().GetProcessSP())
463+
process_sp->RemoveConstituentFromBreakpointSite(GetBreakpoint().GetID(),
464+
GetID(), m_bp_site_sp);
465+
else
466+
m_bp_site_sp->RemoveConstituent(GetBreakpoint().GetID(), GetID());
467+
468+
m_bp_site_sp.reset();
469+
return llvm::Error::success();
468470
}
469471

470472
void BreakpointLocation::GetDescription(Stream *s,

lldb/source/Breakpoint/BreakpointLocationList.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "lldb/Target/SectionLoadList.h"
1616
#include "lldb/Target/Target.h"
1717
#include "lldb/Utility/ArchSpec.h"
18+
#include "lldb/Utility/LLDBLog.h"
19+
#include "lldb/Utility/Log.h"
1820

1921
using namespace lldb;
2022
using namespace lldb_private;
@@ -151,17 +153,24 @@ const BreakpointLocationSP BreakpointLocationList::GetByIndex(size_t i) const {
151153
void BreakpointLocationList::ClearAllBreakpointSites() {
152154
std::lock_guard<std::recursive_mutex> guard(m_mutex);
153155
collection::iterator pos, end = m_locations.end();
154-
for (pos = m_locations.begin(); pos != end; ++pos)
155-
(*pos)->ClearBreakpointSite();
156+
Log *log = GetLog(LLDBLog::Breakpoints);
157+
158+
for (pos = m_locations.begin(); pos != end; ++pos) {
159+
if (llvm::Error error = (*pos)->ClearBreakpointSite())
160+
LLDB_LOG_ERROR(log, std::move(error), "{0}");
161+
}
156162
}
157163

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

162169
for (pos = m_locations.begin(); pos != end; ++pos) {
163-
if ((*pos)->IsEnabled())
164-
(*pos)->ResolveBreakpointSite();
170+
if ((*pos)->IsEnabled()) {
171+
if (llvm::Error error = (*pos)->ResolveBreakpointSite())
172+
LLDB_LOG_ERROR(log, std::move(error), "{0}");
173+
}
165174
}
166175
}
167176

@@ -212,7 +221,8 @@ BreakpointLocationSP BreakpointLocationList::AddLocation(
212221
if (!bp_loc_sp) {
213222
bp_loc_sp = Create(addr, resolve_indirect_symbols);
214223
if (bp_loc_sp) {
215-
bp_loc_sp->ResolveBreakpointSite();
224+
if (llvm::Error error = bp_loc_sp->ResolveBreakpointSite())
225+
LLDB_LOG_ERROR(GetLog(LLDBLog::Breakpoints), std::move(error), "{0}");
216226

217227
if (new_location)
218228
*new_location = true;
@@ -234,7 +244,7 @@ void BreakpointLocationList::SwapLocation(
234244
to_location_sp->SwapLocation(from_location_sp);
235245
RemoveLocation(from_location_sp);
236246
m_address_to_location[to_location_sp->GetAddress()] = to_location_sp;
237-
to_location_sp->ResolveBreakpointSite();
247+
llvm::consumeError(to_location_sp->ResolveBreakpointSite());
238248
}
239249

240250
bool BreakpointLocationList::RemoveLocation(

lldb/source/Breakpoint/BreakpointResolverAddress.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ void BreakpointResolverAddress::ResolveBreakpointInModules(
116116

117117
Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback(
118118
SearchFilter &filter, SymbolContext &context, Address *addr) {
119+
Log *log = GetLog(LLDBLog::Breakpoints);
119120
BreakpointSP breakpoint_sp = GetBreakpoint();
120121
Breakpoint &breakpoint = *breakpoint_sp;
121122

@@ -140,7 +141,6 @@ Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback(
140141
if (bp_loc_sp && !breakpoint.IsInternal()) {
141142
StreamString s;
142143
bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
143-
Log *log = GetLog(LLDBLog::Breakpoints);
144144
LLDB_LOGF(log, "Added location: %s\n", s.GetData());
145145
}
146146
} else {
@@ -149,8 +149,10 @@ Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback(
149149
m_addr.GetLoadAddress(&breakpoint.GetTarget());
150150
if (cur_load_location != m_resolved_addr) {
151151
m_resolved_addr = cur_load_location;
152-
loc_sp->ClearBreakpointSite();
153-
loc_sp->ResolveBreakpointSite();
152+
if (llvm::Error error = loc_sp->ClearBreakpointSite())
153+
LLDB_LOG_ERROR(log, std::move(error), "{0}");
154+
if (llvm::Error error = loc_sp->ResolveBreakpointSite())
155+
LLDB_LOG_ERROR(log, std::move(error), "{0}");
154156
}
155157
}
156158
}

lldb/source/Breakpoint/BreakpointSite.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ BreakpointSite::BreakpointSite(const BreakpointLocationSP &constituent,
3333
BreakpointSite::~BreakpointSite() {
3434
BreakpointLocationSP bp_loc_sp;
3535
const size_t constituent_count = m_constituents.GetSize();
36-
for (size_t i = 0; i < constituent_count; i++) {
37-
m_constituents.GetByIndex(i)->ClearBreakpointSite();
38-
}
36+
for (size_t i = 0; i < constituent_count; i++)
37+
llvm::consumeError(m_constituents.GetByIndex(i)->ClearBreakpointSite());
3938
}
4039

4140
break_id_t BreakpointSite::GetNextID() {

lldb/source/Commands/CommandObjectBreakpoint.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "lldb/Target/ThreadSpec.h"
2929
#include "lldb/Utility/RegularExpression.h"
3030
#include "lldb/Utility/StreamString.h"
31+
#include "llvm/Support/FormatAdapters.h"
3132

3233
#include <memory>
3334
#include <optional>
@@ -956,7 +957,10 @@ class CommandObjectBreakpointEnable : public CommandObjectParsed {
956957
BreakpointLocation *location =
957958
breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
958959
if (location) {
959-
location->SetEnabled(true);
960+
if (llvm::Error error = location->SetEnabled(true))
961+
result.AppendErrorWithFormatv(
962+
"failed to enable breakpoint location: {0}",
963+
llvm::fmt_consume(std::move(error)));
960964
++loc_count;
961965
}
962966
} else {
@@ -1062,7 +1066,10 @@ the second re-enables the first location.");
10621066
BreakpointLocation *location =
10631067
breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
10641068
if (location) {
1065-
location->SetEnabled(false);
1069+
if (llvm::Error error = location->SetEnabled(false))
1070+
result.AppendErrorWithFormatv(
1071+
"failed to disable breakpoint location: {0}",
1072+
llvm::fmt_consume(std::move(error)));
10661073
++loc_count;
10671074
}
10681075
} else {
@@ -1508,7 +1515,10 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
15081515
// It makes no sense to try to delete individual locations, so we
15091516
// disable them instead.
15101517
if (location) {
1511-
location->SetEnabled(false);
1518+
if (llvm::Error error = location->SetEnabled(false))
1519+
result.AppendErrorWithFormatv(
1520+
"failed to disable breakpoint location: {0}",
1521+
llvm::fmt_consume(std::move(error)));
15121522
++disable_count;
15131523
}
15141524
} else {

lldb/source/Commands/CommandObjectProcess.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "lldb/Utility/Args.h"
3636
#include "lldb/Utility/ScriptedMetadata.h"
3737
#include "lldb/Utility/State.h"
38+
#include "llvm/Support/FormatAdapters.h"
3839

3940
#include "llvm/ADT/ScopeExit.h"
4041

@@ -642,8 +643,12 @@ class CommandObjectProcessContinue : public CommandObjectParsed {
642643
BreakpointLocationSP loc_sp = bp_sp->GetLocationAtIndex(loc_idx);
643644
tmp_id.SetBreakpointLocationID(loc_idx);
644645
if (!with_locs.Contains(tmp_id) && loc_sp->IsEnabled()) {
645-
locs_disabled.push_back(tmp_id);
646-
loc_sp->SetEnabled(false);
646+
if (llvm::Error error = loc_sp->SetEnabled(false))
647+
result.AppendErrorWithFormatv(
648+
"failed to disable breakpoint location: {0}",
649+
llvm::fmt_consume(std::move(error)));
650+
else
651+
locs_disabled.push_back(tmp_id);
647652
}
648653
}
649654
}
@@ -698,8 +703,12 @@ class CommandObjectProcessContinue : public CommandObjectParsed {
698703
if (bp_sp) {
699704
BreakpointLocationSP loc_sp
700705
= bp_sp->FindLocationByID(bkpt_id.GetLocationID());
701-
if (loc_sp)
702-
loc_sp->SetEnabled(true);
706+
if (loc_sp) {
707+
if (llvm::Error error = loc_sp->SetEnabled(true))
708+
result.AppendErrorWithFormatv(
709+
"failed to enable breakpoint location: {0}",
710+
llvm::fmt_consume(std::move(error)));
711+
}
703712
}
704713
}
705714

0 commit comments

Comments
 (0)