[llvm] fea987b - [ORC] Fix unchecked Expected<T> in ELFDebugObjectPlugin::FinalizePromise (#172904)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 20 08:11:41 PST 2025
Author: Stefan Gränitz
Date: 2025-12-20T17:11:36+01:00
New Revision: fea987b5eee274357b5ee99d33f1a95ad934fd3a
URL: https://github.com/llvm/llvm-project/commit/fea987b5eee274357b5ee99d33f1a95ad934fd3a
DIFF: https://github.com/llvm/llvm-project/commit/fea987b5eee274357b5ee99d33f1a95ad934fd3a.diff
LOG: [ORC] Fix unchecked Expected<T> in ELFDebugObjectPlugin::FinalizePromise (#172904)
If `Alloc.finalize()` fails in the post-allocation pass, we store the
error in `FinalizePromise`. If we don't reach the post-fixup pass
afterwards the error will leak. This patch adds another case in the
DebugObject destructor that will check the `Expected<T>` and report the
error.
Added:
Modified:
llvm/lib/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.cpp
Removed:
################################################################################
diff --git a/llvm/lib/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.cpp b/llvm/lib/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.cpp
index 5ffc6326938b3..e67eb323c3540 100644
--- a/llvm/lib/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.cpp
@@ -54,15 +54,12 @@ class DebugObject {
MemMgr(Ctx.getMemoryManager()), ES(ES) {}
~DebugObject() {
+ assert(!FinalizeFuture.valid());
if (Alloc) {
std::vector<FinalizedAlloc> Allocs;
Allocs.push_back(std::move(Alloc));
if (Error Err = MemMgr.deallocate(std::move(Allocs)))
ES.reportError(std::move(Err));
- } else if (!FinalizeFuture.valid()) {
- // WorkingMem was not finalized
- WorkingMem.abandon(
- [ES = &this->ES](Error Err) { ES->reportError(std::move(Err)); });
}
}
@@ -71,7 +68,7 @@ class DebugObject {
return SegInfo.WorkingMem;
}
- SimpleSegmentAlloc takeTargetAlloc() {
+ SimpleSegmentAlloc collectTargetAlloc() {
FinalizeFuture = FinalizePromise.get_future();
return std::move(WorkingMem);
}
@@ -88,6 +85,19 @@ class DebugObject {
FinalizePromise.set_value(std::move(Err));
}
+ void releasePendingResources() {
+ if (FinalizeFuture.valid()) {
+ // Error before step 4: Finalization error was not reported
+ Expected<ExecutorAddrRange> TargetMem = FinalizeFuture.get();
+ if (!TargetMem)
+ ES.reportError(TargetMem.takeError());
+ } else {
+ // Error before step 3: WorkingMem was not collected
+ WorkingMem.abandon(
+ [ES = &this->ES](Error Err) { ES->reportError(std::move(Err)); });
+ }
+ }
+
using GetLoadAddressFn = llvm::unique_function<ExecutorAddr(StringRef)>;
Error visitSections(GetLoadAddressFn Callback);
@@ -296,7 +306,7 @@ void ELFDebugObjectPlugin::modifyPassConfig(MaterializationResponsibility &MR,
}
// Step 3: We start copying the debug object into target memory
- SimpleSegmentAlloc Alloc = DebugObj->takeTargetAlloc();
+ SimpleSegmentAlloc Alloc = DebugObj->collectTargetAlloc();
// FIXME: FA->getAddress() below is supposed to be the address of the memory
// range on the target, but InProcessMemoryManager returns the address of a
@@ -304,7 +314,16 @@ void ELFDebugObjectPlugin::modifyPassConfig(MaterializationResponsibility &MR,
auto ROSeg = Alloc.getSegInfo(MemProt::Read);
ExecutorAddrRange R(ROSeg.Addr, ROSeg.WorkingMem.size());
Alloc.finalize([this, R, &MR](Expected<DebugObject::FinalizedAlloc> FA) {
- DebugObject *DebugObj = getPendingDebugObj(MR);
+ // Bail out if materialization failed in the meantime
+ std::lock_guard<std::mutex> Lock(PendingObjsLock);
+ auto It = PendingObjs.find(&MR);
+ if (It == PendingObjs.end()) {
+ if (!FA)
+ ES.reportError(FA.takeError());
+ return;
+ }
+
+ DebugObject *DebugObj = It->second.get();
if (!FA)
DebugObj->failMaterialization(FA.takeError());
@@ -355,7 +374,9 @@ void ELFDebugObjectPlugin::modifyPassConfig(MaterializationResponsibility &MR,
Error ELFDebugObjectPlugin::notifyFailed(MaterializationResponsibility &MR) {
std::lock_guard<std::mutex> Lock(PendingObjsLock);
- PendingObjs.erase(&MR);
+ auto It = PendingObjs.find(&MR);
+ It->second->releasePendingResources();
+ PendingObjs.erase(It);
return Error::success();
}
More information about the llvm-commits
mailing list