[ORC] Remove EDU from dependants list of dependencies before destroying.
authorLang Hames <lhames@gmail.com>
Tue, 10 Sep 2024 03:47:17 +0000 (13:47 +1000)
committerTobias Hieta <tobias@hieta.se>
Tue, 24 Sep 2024 06:42:36 +0000 (08:42 +0200)
Dependant lists hold raw pointers back to EDUs that depend on them. We need to
remove these entries before destroying the EDU or we'll be left with a dangling
reference that can result in use-after-free bugs.

No testcase: This has only been observed in multi-threaded setups that
reproduce the issue inconsistently.

rdar://135403614
(cherry picked from commit 7034ec491251e598d2867199f89fefa3eb16a1a0)

llvm/lib/ExecutionEngine/Orc/Core.cpp

index 3e6de62c8b7dd99c5b8f0a0feb297f266c5dcc3a..f70c2890521d3df4638dd28e92dd70c4b898f7d4 100644 (file)
@@ -3592,6 +3592,21 @@ ExecutionSession::IL_failSymbols(JITDylib &JD,
       assert(MI.DefiningEDU->Symbols.count(NonOwningSymbolStringPtr(Name)) &&
              "Symbol does not appear in its DefiningEDU");
       MI.DefiningEDU->Symbols.erase(NonOwningSymbolStringPtr(Name));
+
+      // Remove this EDU from the dependants lists of its dependencies.
+      for (auto &[DepJD, DepSyms] : MI.DefiningEDU->Dependencies) {
+        for (auto DepSym : DepSyms) {
+          assert(DepJD->Symbols.count(SymbolStringPtr(DepSym)) &&
+                 "DepSym not in DepJD");
+          assert(DepJD->MaterializingInfos.count(SymbolStringPtr(DepSym)) &&
+                 "DepSym has not MaterializingInfo");
+          auto &SymMI = DepJD->MaterializingInfos[SymbolStringPtr(DepSym)];
+          assert(SymMI.DependantEDUs.count(MI.DefiningEDU.get()) &&
+                 "DefiningEDU missing from DependantEDUs list of dependency");
+          SymMI.DependantEDUs.erase(MI.DefiningEDU.get());
+        }
+      }
+
       MI.DefiningEDU = nullptr;
     } else {
       // Otherwise if there are any EDUs waiting on this symbol then move