[llvm] 21b5ebd - [ORC][LLJIT] Add LLJITBuilder convenience function to enable debugger support.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 16 12:23:39 PDT 2023


Author: Lang Hames
Date: 2023-04-16T12:23:33-07:00
New Revision: 21b5ebd245c88c81fe09248c7dce5cc3e0e56cae

URL: https://github.com/llvm/llvm-project/commit/21b5ebd245c88c81fe09248c7dce5cc3e0e56cae
DIFF: https://github.com/llvm/llvm-project/commit/21b5ebd245c88c81fe09248c7dce5cc3e0e56cae.diff

LOG: [ORC][LLJIT] Add LLJITBuilder convenience function to enable debugger support.

Clients can now call LLJITBuilder::setEnableDebuggerSupport to enable
registration of debug info via the GDB-JIT registration protocol for JIT'd
code.

Calling LLJITBuilder::setEnableDebuggerSupport(true) will cause LLJITBuilder to
add either a DebugObjectManagerPlugin (if the object format on the triple is
ELF), or a GDBJITDebugInfoRegistrationPlugin (if the object format on the
triple is MachO). At present there is no support for debugging when using COFF.

This debugger registration support will only work when JITLink is used as the
underlying JIT linker.

This patch only addresses registration of JIT'd code by the JIT. To debug JIT'd
code you may also need to enable JIT'd code debugging in your debugger. E.g.
when debugging MachO JIT'd code under LLDB you will currently need to run
(lldb) set set plugin.jit-loader.gdb.enable on
to tell LLDB to listen for JIT'd code registration.

Added: 
    

Modified: 
    llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
    llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
    llvm/tools/lli/lli.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
index abc1c0c781619..76600e22c3164 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -320,6 +320,7 @@ class LLJITBuilderState {
   CompileFunctionCreator CreateCompileFunction;
   PlatformSetupFunction SetUpPlatform;
   unsigned NumCompileThreads = 0;
+  bool EnableDebuggerSupport = false;
 
   /// Called prior to JIT class construcion to fix up defaults.
   Error prepareForConstruction();
@@ -439,6 +440,12 @@ class LLJITBuilderSetters {
     return impl();
   }
 
+  /// Enable / disable debugger support (off by default).
+  SetterImpl &setEnableDebuggerSupport(bool EnableDebuggerSupport) {
+    impl().EnableDebuggerSupport = EnableDebuggerSupport;
+    return impl();
+  }
+
   /// Set an ExecutorProcessControl object.
   ///
   /// If the platform uses ObjectLinkingLayer by default and no

diff  --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
index bc37b39950184..a65c3567c1487 100644
--- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
@@ -10,6 +10,8 @@
 #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
 #include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
+#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
+#include "llvm/ExecutionEngine/Orc/DebuggerSupportPlugin.h"
 #include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
 #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
 #include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
@@ -704,6 +706,14 @@ Error LLJITBuilderState::prepareForConstruction() {
       dbgs() << "\n";
   });
 
+  // Create DL if not specified.
+  if (!DL) {
+    if (auto DLOrErr = JTMB->getDefaultDataLayoutForTarget())
+      DL = std::move(*DLOrErr);
+    else
+      return DLOrErr.takeError();
+  }
+
   // If neither ES nor EPC has been set then create an EPC instance.
   if (!ES && !EPC) {
     LLVM_DEBUG({
@@ -763,6 +773,30 @@ Error LLJITBuilderState::prepareForConstruction() {
     }
   }
 
+  // If we need a process JITDylib but no setup function has been given then
+  // create a default one.
+  if (!SetupProcessSymbolsJITDylib &&
+      (LinkProcessSymbolsByDefault || EnableDebuggerSupport)) {
+
+    LLVM_DEBUG({
+      dbgs() << "Creating default Process JD setup function (neeeded for";
+      if (LinkProcessSymbolsByDefault)
+        dbgs() << " <link-process-syms-by-default>";
+      if (EnableDebuggerSupport)
+        dbgs() << " <debugger-support>";
+      dbgs() << ")\n";
+    });
+
+    SetupProcessSymbolsJITDylib = [this](JITDylib &JD) -> Error {
+      auto G = orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
+          DL->getGlobalPrefix());
+      if (!G)
+        return G.takeError();
+      JD.addGenerator(std::move(*G));
+      return Error::success();
+    };
+  }
+
   return Error::success();
 }
 
@@ -906,7 +940,7 @@ LLJIT::createCompileFunction(LLJITBuilderState &S,
 }
 
 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
-    : DL(""), TT(S.JTMB->getTargetTriple()) {
+    : DL(std::move(*S.DL)), TT(S.JTMB->getTargetTriple()) {
 
   ErrorAsOutParameter _(&Err);
 
@@ -925,15 +959,6 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
     }
   }
 
-  if (S.DL)
-    DL = std::move(*S.DL);
-  else if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
-    DL = std::move(*DLOrErr);
-  else {
-    Err = DLOrErr.takeError();
-    return;
-  }
-
   auto ObjLayer = createObjectLinkingLayer(S, *ES);
   if (!ObjLayer) {
     Err = ObjLayer.takeError();
@@ -972,16 +997,6 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
     });
   }
 
-  if (S.LinkProcessSymbolsByDefault && !S.SetupProcessSymbolsJITDylib)
-    S.SetupProcessSymbolsJITDylib = [this](JITDylib &JD) -> Error {
-      auto G = orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
-          DL.getGlobalPrefix());
-      if (!G)
-        return G.takeError();
-      JD.addGenerator(std::move(*G));
-      return Error::success();
-    };
-
   if (S.SetupProcessSymbolsJITDylib) {
     ProcessSymbols = &ES->createBareJITDylib("<Process Symbols>");
     if (auto Err2 = S.SetupProcessSymbolsJITDylib(*ProcessSymbols)) {
@@ -990,6 +1005,46 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
     }
   }
 
+  if (S.EnableDebuggerSupport) {
+    if (auto *OLL = dyn_cast<ObjectLinkingLayer>(ObjLinkingLayer.get())) {
+      switch (TT.getObjectFormat()) {
+      case Triple::ELF: {
+        auto Registrar = createJITLoaderGDBRegistrar(*ES);
+        if (!Registrar) {
+          Err = Registrar.takeError();
+          return;
+        }
+        OLL->addPlugin(std::make_unique<DebugObjectManagerPlugin>(
+            *ES, std::move(*Registrar), true, true));
+        break;
+      }
+      case Triple::MachO: {
+        assert(ProcessSymbols && "ProcessSymbols JD should be available when "
+                                 "EnableDebuggerSupport is set");
+        auto DS =
+            GDBJITDebugInfoRegistrationPlugin::Create(*ES, *ProcessSymbols, TT);
+        if (!DS) {
+          Err = DS.takeError();
+          return;
+        }
+        OLL->addPlugin(std::move(*DS));
+        break;
+      }
+      default:
+        LLVM_DEBUG({
+          dbgs() << "Cannot enable LLJIT debugger support: "
+                 << Triple::getObjectFormatTypeName(TT.getObjectFormat())
+                 << " not supported.\n";
+        });
+      }
+    } else {
+      LLVM_DEBUG({
+        dbgs() << "Cannot enable LLJIT debugger support: "
+                  " debugger support is only available when using JITLink.\n";
+      });
+    }
+  }
+
   if (!S.SetUpPlatform)
     S.SetUpPlatform = setUpGenericLLVMIRPlatform;
 

diff  --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index 368a8baca07da..bc1c9cecbb772 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -25,9 +25,7 @@
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/MCJIT.h"
 #include "llvm/ExecutionEngine/ObjectCache.h"
-#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
 #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
-#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
 #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
 #include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
 #include "llvm/ExecutionEngine/Orc/EPCGenericRTDyldMemoryManager.h"
@@ -935,16 +933,16 @@ int runOrcJIT(const char *ProgName) {
     Builder.setObjectLinkingLayerCreator([&EPC, &P](orc::ExecutionSession &ES,
                                                     const Triple &TT) {
       auto L = std::make_unique<orc::ObjectLinkingLayer>(ES, EPC->getMemMgr());
-      if (P != LLJITPlatform::ExecutorNative) {
+      if (P != LLJITPlatform::ExecutorNative)
         L->addPlugin(std::make_unique<orc::EHFrameRegistrationPlugin>(
             ES, ExitOnErr(orc::EPCEHFrameRegistrar::Create(ES))));
-        L->addPlugin(std::make_unique<orc::DebugObjectManagerPlugin>(
-            ES, ExitOnErr(orc::createJITLoaderGDBRegistrar(ES)), true, true));
-      }
       return L;
     });
   }
 
+  // Enable debugging of JIT'd code (only works on JITLink for ELF and MachO).
+  Builder.setEnableDebuggerSupport(true);
+
   auto J = ExitOnErr(Builder.create());
 
   auto *ObjLayer = &J->getObjLinkingLayer();


        


More information about the llvm-commits mailing list