[Lldb-commits] [lldb] Add new API in SBTarget for loading core from SBFile (PR #71769)

via lldb-commits lldb-commits at lists.llvm.org
Tue Nov 14 21:21:11 PST 2023


https://github.com/GeorgeHuyubo updated https://github.com/llvm/llvm-project/pull/71769

>From 76f7fd2c62921f15c35b4dd57cc6bfa8a8be93b2 Mon Sep 17 00:00:00 2001
From: George Hu <huyubohyb at gmail.com>
Date: Wed, 8 Nov 2023 16:25:34 -0800
Subject: [PATCH] Add new API in SBTarget for loading core from SBFile

---
 lldb/include/lldb/API/SBTarget.h              |  1 +
 lldb/include/lldb/Target/PostMortemProcess.h  | 15 ++++++++
 lldb/include/lldb/Target/Process.h            | 10 +++++-
 lldb/include/lldb/Target/ProcessTrace.h       |  5 +--
 lldb/include/lldb/Target/Target.h             |  3 +-
 lldb/include/lldb/lldb-private-interfaces.h   |  7 ++--
 lldb/source/API/SBTarget.cpp                  | 34 +++++++++++++++++--
 lldb/source/Commands/CommandObjectTarget.cpp  | 11 +++++-
 lldb/source/Core/IOHandlerCursesGUI.cpp       | 13 +++++--
 .../FreeBSDKernel/ProcessFreeBSDKernel.cpp    | 27 +++++++++------
 .../FreeBSDKernel/ProcessFreeBSDKernel.h      |  8 ++---
 .../Process/MacOSX-Kernel/ProcessKDP.cpp      |  4 +--
 .../Process/MacOSX-Kernel/ProcessKDP.h        |  9 ++---
 .../Process/elf-core/ProcessElfCore.cpp       | 22 ++++++------
 .../Plugins/Process/elf-core/ProcessElfCore.h | 12 +++----
 .../Process/gdb-remote/ProcessGDBRemote.cpp   |  9 ++---
 .../Process/gdb-remote/ProcessGDBRemote.h     |  3 +-
 .../Process/mach-core/ProcessMachCore.cpp     | 23 +++++++------
 .../Process/mach-core/ProcessMachCore.h       | 11 +++---
 .../Process/minidump/ProcessMinidump.cpp      | 16 +++++----
 .../Process/minidump/ProcessMinidump.h        |  6 ++--
 .../Process/scripted/ScriptedProcess.cpp      |  2 +-
 .../Process/scripted/ScriptedProcess.h        |  2 +-
 lldb/source/Target/Process.cpp                |  7 ++--
 lldb/source/Target/ProcessTrace.cpp           | 11 +++---
 lldb/source/Target/Target.cpp                 |  2 +-
 .../postmortem/elf-core/TestLinuxCore.py      | 16 +++++++++
 .../Target/LocateModuleCallbackTest.cpp       |  3 +-
 28 files changed, 198 insertions(+), 94 deletions(-)

diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 83087623088c5b4..afc949390ac3379 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -184,6 +184,7 @@ class LLDB_API SBTarget {
 
   SBProcess LoadCore(const char *core_file);
   SBProcess LoadCore(const char *core_file, lldb::SBError &error);
+  SBProcess LoadCore(SBFile &file, lldb::SBError &error);
 
   /// Launch a new process with sensible defaults.
   ///
diff --git a/lldb/include/lldb/Target/PostMortemProcess.h b/lldb/include/lldb/Target/PostMortemProcess.h
index 7207fc99ef29a41..2bd775c9e2c5196 100644
--- a/lldb/include/lldb/Target/PostMortemProcess.h
+++ b/lldb/include/lldb/Target/PostMortemProcess.h
@@ -10,6 +10,8 @@
 #define LLDB_TARGET_POSTMORTEMPROCESS_H
 
 #include "lldb/Target/Process.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/lldb-forward.h"
 
 namespace lldb_private {
 
@@ -24,7 +26,20 @@ class PostMortemProcess : public Process {
   using Process::Process;
 
 public:
+  PostMortemProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+                    lldb::FileSP file_sp)
+      : Process(target_sp, listener_sp), m_core_file(file_sp) {}
+
   bool IsLiveDebugSession() const override { return false; }
+
+  FileSpec GetCoreFile() const override {
+    FileSpec file_spec;
+    m_core_file->GetFileSpec(file_spec);
+    return file_spec;
+  }
+
+protected:
+  lldb::FileSP m_core_file;
 };
 
 } // namespace lldb_private
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index a6d3e6c2d16926e..6e2cafbfce9698e 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -52,6 +52,7 @@
 #include "lldb/Utility/TraceGDBRemotePackets.h"
 #include "lldb/Utility/UnimplementedError.h"
 #include "lldb/Utility/UserIDResolver.h"
+#include "lldb/lldb-forward.h"
 #include "lldb/lldb-private.h"
 
 #include "llvm/ADT/ArrayRef.h"
@@ -507,7 +508,7 @@ class Process : public std::enable_shared_from_this<Process>,
   static lldb::ProcessSP FindPlugin(lldb::TargetSP target_sp,
                                     llvm::StringRef plugin_name,
                                     lldb::ListenerSP listener_sp,
-                                    const FileSpec *crash_file_path,
+                                    lldb::FileSP crash_file_sp,
                                     bool can_connect);
 
   /// Static function that can be used with the \b host function
@@ -1469,6 +1470,13 @@ class Process : public std::enable_shared_from_this<Process>,
 
   virtual bool IsLiveDebugSession() const { return true; };
 
+  /// Provide a way to retrieve the core dump file that is loaded for debugging.
+  /// Only available if IsLiveDebugSession() returns false.
+  ///
+  /// \return
+  ///     File path to the core file.
+  virtual FileSpec GetCoreFile() const { return {}; }
+
   /// Before lldb detaches from a process, it warns the user that they are
   /// about to lose their debug session. In some cases, this warning doesn't
   /// need to be emitted -- for instance, with core file debugging where the
diff --git a/lldb/include/lldb/Target/ProcessTrace.h b/lldb/include/lldb/Target/ProcessTrace.h
index 037dea232cc024d..de535243744a1f3 100644
--- a/lldb/include/lldb/Target/ProcessTrace.h
+++ b/lldb/include/lldb/Target/ProcessTrace.h
@@ -27,7 +27,8 @@ class ProcessTrace : public PostMortemProcess {
 
   static llvm::StringRef GetPluginDescriptionStatic();
 
-  ProcessTrace(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+  ProcessTrace(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
+               lldb::FileSP core_file_sp);
 
   ~ProcessTrace() override;
 
@@ -74,7 +75,7 @@ class ProcessTrace : public PostMortemProcess {
 private:
   static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
                                         lldb::ListenerSP listener_sp,
-                                        const FileSpec *crash_file_path,
+                                        lldb::FileSP core_file_sp,
                                         bool can_connect);
 };
 
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index c37682e2a03859f..a84b8a30dd15c65 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -35,6 +35,7 @@
 #include "lldb/Utility/Broadcaster.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/Timeout.h"
+#include "lldb/lldb-forward.h"
 #include "lldb/lldb-public.h"
 
 namespace lldb_private {
@@ -627,7 +628,7 @@ class Target : public std::enable_shared_from_this<Target>,
   // used.
   const lldb::ProcessSP &CreateProcess(lldb::ListenerSP listener_sp,
                                        llvm::StringRef plugin_name,
-                                       const FileSpec *crash_file,
+                                       lldb::FileSP crash_file,
                                        bool can_connect);
 
   const lldb::ProcessSP &GetProcessSP() const;
diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h
index 53d5fbb84cc92d3..55f2c794c274ab8 100644
--- a/lldb/include/lldb/lldb-private-interfaces.h
+++ b/lldb/include/lldb/lldb-private-interfaces.h
@@ -77,9 +77,10 @@ typedef Status (*StructuredDataFilterLaunchInfo)(ProcessLaunchInfo &launch_info,
 typedef SystemRuntime *(*SystemRuntimeCreateInstance)(Process *process);
 typedef lldb::PlatformSP (*PlatformCreateInstance)(bool force,
                                                    const ArchSpec *arch);
-typedef lldb::ProcessSP (*ProcessCreateInstance)(
-    lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
-    const FileSpec *crash_file_path, bool can_connect);
+typedef lldb::ProcessSP (*ProcessCreateInstance)(lldb::TargetSP target_sp,
+                                                 lldb::ListenerSP listener_sp,
+                                                 lldb::FileSP crash_file_sp,
+                                                 bool can_connect);
 typedef lldb::RegisterTypeBuilderSP (*RegisterTypeBuilderCreateInstance)(
     Target &target);
 typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 2d029554492a05c..8d970bbde79a87e 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -16,6 +16,7 @@
 #include "lldb/API/SBEnvironment.h"
 #include "lldb/API/SBEvent.h"
 #include "lldb/API/SBExpressionOptions.h"
+#include "lldb/API/SBFile.h"
 #include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBListener.h"
 #include "lldb/API/SBModule.h"
@@ -244,9 +245,38 @@ SBProcess SBTarget::LoadCore(const char *core_file, lldb::SBError &error) {
   TargetSP target_sp(GetSP());
   if (target_sp) {
     FileSpec filespec(core_file);
-    FileSystem::Instance().Resolve(filespec);
+    auto file = FileSystem::Instance().Open(
+        filespec, lldb_private::File::eOpenOptionReadOnly);
+    if (!file) {
+      error.SetErrorStringWithFormat("Failed to open the core file: %s",
+                                     llvm::toString(file.takeError()).c_str());
+      return sb_process;
+    }
+    ProcessSP process_sp(
+        target_sp->CreateProcess(target_sp->GetDebugger().GetListener(), "",
+                                 std::move(file.get()), false));
+    if (process_sp) {
+      error.SetError(process_sp->LoadCore());
+      if (error.Success())
+        sb_process.SetSP(process_sp);
+    } else {
+      error.SetErrorString("Failed to create the process");
+    }
+  } else {
+    error.SetErrorString("SBTarget is invalid");
+  }
+  return sb_process;
+}
+
+SBProcess SBTarget::LoadCore(SBFile &file, lldb::SBError &error) {
+  LLDB_INSTRUMENT_VA(this, file, error);
+
+  SBProcess sb_process;
+  TargetSP target_sp(GetSP());
+  if (target_sp) {
+    FileSP file_sp = file.GetFile();
     ProcessSP process_sp(target_sp->CreateProcess(
-        target_sp->GetDebugger().GetListener(), "", &filespec, false));
+        target_sp->GetDebugger().GetListener(), "", file_sp, false));
     if (process_sp) {
       error.SetError(process_sp->LoadCore());
       if (error.Success())
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 8f052d0a7b837e2..5afc028a9d893cb 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -427,8 +427,17 @@ class CommandObjectTargetCreate : public CommandObjectParsed {
         core_file_dir.SetDirectory(core_file.GetDirectory());
         target_sp->AppendExecutableSearchPaths(core_file_dir);
 
+        auto file = FileSystem::Instance().Open(
+            core_file, lldb_private::File::eOpenOptionReadOnly);
+        if (!file) {
+          result.AppendErrorWithFormatv(
+              "Failed to open the core file '{0}': '{1}.'\n",
+              core_file.GetPath(), llvm::toString(file.takeError()));
+        }
+
         ProcessSP process_sp(target_sp->CreateProcess(
-            GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
+            GetDebugger().GetListener(), llvm::StringRef(),
+            std::move(file.get()), false));
 
         if (process_sp) {
           // Seems weird that we Launch a core file, but that is what we
diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp
index 22b8cc3582eae78..5b850fd5d5d7438 100644
--- a/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -3174,8 +3174,17 @@ class TargetCreateFormDelegate : public FormDelegate {
     core_file_directory_spec.SetDirectory(core_file_spec.GetDirectory());
     target_sp->AppendExecutableSearchPaths(core_file_directory_spec);
 
-    ProcessSP process_sp(target_sp->CreateProcess(
-        m_debugger.GetListener(), llvm::StringRef(), &core_file_spec, false));
+    auto core_file = FileSystem::Instance().Open(
+        core_file_spec, lldb_private::File::eOpenOptionReadOnly);
+
+    if (!core_file) {
+      SetError(llvm::toString(core_file.takeError()).c_str());
+      return;
+    }
+
+    ProcessSP process_sp(
+        target_sp->CreateProcess(m_debugger.GetListener(), llvm::StringRef(),
+                                 std::move(core_file.get()), false));
 
     if (!process_sp) {
       SetError("Unable to find process plug-in for core file!");
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index 601f5df43dbba4e..9fdd59ec2be8963 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -32,7 +32,7 @@ namespace {
 class ProcessFreeBSDKernelFVC : public ProcessFreeBSDKernel {
 public:
   ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp, lldb::ListenerSP listener,
-                          fvc_t *fvc);
+                          lldb::FileSP core_file_sp, fvc_t *fvc);
 
   ~ProcessFreeBSDKernelFVC();
 
@@ -50,7 +50,7 @@ class ProcessFreeBSDKernelFVC : public ProcessFreeBSDKernel {
 class ProcessFreeBSDKernelKVM : public ProcessFreeBSDKernel {
 public:
   ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp, lldb::ListenerSP listener,
-                          kvm_t *fvc);
+                          lldb::FileSP core_file_sp, kvm_t *fvc);
 
   ~ProcessFreeBSDKernelKVM();
 
@@ -67,31 +67,34 @@ class ProcessFreeBSDKernelKVM : public ProcessFreeBSDKernel {
 } // namespace
 
 ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp,
-                                           ListenerSP listener_sp)
-    : PostMortemProcess(target_sp, listener_sp) {}
+                                           ListenerSP listener_sp,
+                                           lldb::FileSP crash_file_sp)
+    : PostMortemProcess(target_sp, listener_sp, crash_file_sp) {}
 
 lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp,
                                                      ListenerSP listener_sp,
-                                                     const FileSpec *crash_file,
+                                                     lldb::FileSP crash_file_sp,
                                                      bool can_connect) {
   ModuleSP executable = target_sp->GetExecutableModule();
   if (crash_file && !can_connect && executable) {
+    FileSpec file_spec;
+    crash_file_sp->GetFileSpec(file_spec);
 #if LLDB_ENABLE_FBSDVMCORE
     fvc_t *fvc =
         fvc_open(executable->GetFileSpec().GetPath().c_str(),
-                 crash_file->GetPath().c_str(), nullptr, nullptr, nullptr);
+                 file_spec->GetPath().c_str(), nullptr, nullptr, nullptr);
     if (fvc)
       return std::make_shared<ProcessFreeBSDKernelFVC>(target_sp, listener_sp,
-                                                       fvc);
+                                                       crash_file_sp fvc);
 #endif
 
 #if defined(__FreeBSD__)
     kvm_t *kvm =
         kvm_open2(executable->GetFileSpec().GetPath().c_str(),
-                  crash_file->GetPath().c_str(), O_RDONLY, nullptr, nullptr);
+                  file_spec->GetPath().c_str(), O_RDONLY, nullptr, nullptr);
     if (kvm)
       return std::make_shared<ProcessFreeBSDKernelKVM>(target_sp, listener_sp,
-                                                       kvm);
+                                                       crash_file_sp kvm);
 #endif
   }
   return nullptr;
@@ -276,8 +279,9 @@ lldb::addr_t ProcessFreeBSDKernel::FindSymbol(const char *name) {
 
 ProcessFreeBSDKernelFVC::ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp,
                                                  ListenerSP listener_sp,
+                                                 lldb::FileSP core_file_sp,
                                                  fvc_t *fvc)
-    : ProcessFreeBSDKernel(target_sp, listener_sp), m_fvc(fvc) {}
+    : ProcessFreeBSDKernel(target_sp, listener_sp, core_file_sp), m_fvc(fvc) {}
 
 ProcessFreeBSDKernelFVC::~ProcessFreeBSDKernelFVC() {
   if (m_fvc)
@@ -303,8 +307,9 @@ const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); }
 
 ProcessFreeBSDKernelKVM::ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp,
                                                  ListenerSP listener_sp,
+                                                 lldb::FileSP core_file_sp,
                                                  kvm_t *fvc)
-    : ProcessFreeBSDKernel(target_sp, listener_sp), m_kvm(fvc) {}
+    : ProcessFreeBSDKernel(target_sp, listener_sp, core_file_sp), m_kvm(fvc) {}
 
 ProcessFreeBSDKernelKVM::~ProcessFreeBSDKernelKVM() {
   if (m_kvm)
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
index 5bd463126307cd9..5f528676bec7a21 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -15,10 +15,10 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
 public:
   ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener);
 
-  static lldb::ProcessSP
-  CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
-                 const lldb_private::FileSpec *crash_file_path,
-                 bool can_connect);
+  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+                                        lldb::ListenerSP listener,
+                                        lldb::FileSP crash_file_sp,
+                                        bool can_connect);
 
   static void Initialize();
 
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index e0956b49ae1f151..00b303eb53cbfbb 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -102,10 +102,10 @@ void ProcessKDP::Terminate() {
 
 lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,
                                            ListenerSP listener_sp,
-                                           const FileSpec *crash_file_path,
+                                           FileSP crash_file_sp,
                                            bool can_connect) {
   lldb::ProcessSP process_sp;
-  if (crash_file_path == NULL)
+  if (crash_file_sp)
     process_sp = std::make_shared<ProcessKDP>(target_sp, listener_sp);
   return process_sp;
 }
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 3c12fd4074499a9..5b20fae6a689130 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -24,16 +24,17 @@
 #include "lldb/Utility/StringList.h"
 
 #include "CommunicationKDP.h"
+#include "lldb/lldb-forward.h"
 
 class ThreadKDP;
 
 class ProcessKDP : public lldb_private::Process {
 public:
   // Constructors and Destructors
-  static lldb::ProcessSP
-  CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
-                 const lldb_private::FileSpec *crash_file_path,
-                 bool can_connect);
+  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+                                        lldb::ListenerSP listener_sp,
+                                        lldb::FileSP crash_file_sp,
+                                        bool can_connect);
 
   static void Initialize();
 
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index aedc43a015ff12b..5f8dfff987592c7 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -33,6 +33,7 @@
 #include "Plugins/Process/elf-core/RegisterUtilities.h"
 #include "ProcessElfCore.h"
 #include "ThreadElfCore.h"
+#include "lldb/lldb-forward.h"
 
 using namespace lldb_private;
 namespace ELF = llvm::ELF;
@@ -49,17 +50,18 @@ void ProcessElfCore::Terminate() {
 
 lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
                                                lldb::ListenerSP listener_sp,
-                                               const FileSpec *crash_file,
+                                               lldb::FileSP crash_file_sp,
                                                bool can_connect) {
   lldb::ProcessSP process_sp;
-  if (crash_file && !can_connect) {
+  if (crash_file_sp && !can_connect) {
     // Read enough data for an ELF32 header or ELF64 header Note: Here we care
     // about e_type field only, so it is safe to ignore possible presence of
     // the header extension.
     const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
-
-    auto data_sp = FileSystem::Instance().CreateDataBuffer(
-        crash_file->GetPath(), header_size, 0);
+    FileSpec file_spec;
+    crash_file_sp->GetFileSpec(file_spec);
+    auto data_sp = FileSystem::Instance().CreateDataBuffer(file_spec.GetPath(),
+                                                           header_size, 0);
     if (data_sp && data_sp->GetByteSize() == header_size &&
         elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
       elf::ELFHeader elf_header;
@@ -72,7 +74,7 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
           return process_sp;
         if (elf_header.e_type == llvm::ELF::ET_CORE)
           process_sp = std::make_shared<ProcessElfCore>(target_sp, listener_sp,
-                                                        *crash_file);
+                                                        crash_file_sp);
       }
     }
   }
@@ -82,8 +84,8 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
 bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
                               bool plugin_specified_by_name) {
   // For now we are just making sure the file exists for a given module
-  if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
-    ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
+  if (!m_core_module_sp && FileSystem::Instance().Exists(GetCoreFile())) {
+    ModuleSpec core_module_spec(GetCoreFile(), target_sp->GetArchitecture());
     Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
                                              nullptr, nullptr, nullptr));
     if (m_core_module_sp) {
@@ -98,8 +100,8 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
 // ProcessElfCore constructor
 ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
                                lldb::ListenerSP listener_sp,
-                               const FileSpec &core_file)
-    : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file) {}
+                               lldb::FileSP core_file_sp)
+    : PostMortemProcess(target_sp, listener_sp, core_file_sp) {}
 
 // Destructor
 ProcessElfCore::~ProcessElfCore() {
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index 1454e8735a677b5..f005f0423f4282b 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -24,16 +24,17 @@
 
 #include "Plugins/ObjectFile/ELF/ELFHeader.h"
 #include "Plugins/Process/elf-core/RegisterUtilities.h"
+#include "lldb/lldb-forward.h"
 
 struct ThreadData;
 
 class ProcessElfCore : public lldb_private::PostMortemProcess {
 public:
   // Constructors and Destructors
-  static lldb::ProcessSP
-  CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
-                 const lldb_private::FileSpec *crash_file_path,
-                 bool can_connect);
+  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+                                        lldb::ListenerSP listener_sp,
+                                        lldb::FileSP crash_file_sp,
+                                        bool can_connect);
 
   static void Initialize();
 
@@ -45,7 +46,7 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
 
   // Constructors and Destructors
   ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
-                 const lldb_private::FileSpec &core_file);
+                 lldb::FileSP core_file_sp);
 
   ~ProcessElfCore() override;
 
@@ -127,7 +128,6 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
       VMRangeToPermissions;
 
   lldb::ModuleSP m_core_module_sp;
-  lldb_private::FileSpec m_core_file;
   std::string m_dyld_plugin_name;
 
   // True if m_thread_contexts contains valid entries
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index f90a561aae2e3b7..67a25f8a0146f67 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -194,11 +194,12 @@ void ProcessGDBRemote::Terminate() {
   PluginManager::UnregisterPlugin(ProcessGDBRemote::CreateInstance);
 }
 
-lldb::ProcessSP ProcessGDBRemote::CreateInstance(
-    lldb::TargetSP target_sp, ListenerSP listener_sp,
-    const FileSpec *crash_file_path, bool can_connect) {
+lldb::ProcessSP ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
+                                                 ListenerSP listener_sp,
+                                                 lldb::FileSP crash_file_sp,
+                                                 bool can_connect) {
   lldb::ProcessSP process_sp;
-  if (crash_file_path == nullptr)
+  if (crash_file_sp)
     process_sp = std::shared_ptr<ProcessGDBRemote>(
         new ProcessGDBRemote(target_sp, listener_sp));
   return process_sp;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index f3787e7169047e2..cb598bede04c288 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -32,6 +32,7 @@
 #include "lldb/Utility/StringExtractor.h"
 #include "lldb/Utility/StringList.h"
 #include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-forward.h"
 #include "lldb/lldb-private-forward.h"
 
 #include "GDBRemoteCommunicationClient.h"
@@ -55,7 +56,7 @@ class ProcessGDBRemote : public Process,
 
   static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
                                         lldb::ListenerSP listener_sp,
-                                        const FileSpec *crash_file_path,
+                                        lldb::FileSP core_file_sp,
                                         bool can_connect);
 
   static void Initialize();
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 9830a4b8599dff8..b934b14b006a054 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -42,6 +42,7 @@
 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
 #include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
+#include "lldb/lldb-forward.h"
 
 #include <memory>
 #include <mutex>
@@ -61,13 +62,15 @@ void ProcessMachCore::Terminate() {
 
 lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
                                                 ListenerSP listener_sp,
-                                                const FileSpec *crash_file,
+                                                lldb::FileSP crash_file_sp,
                                                 bool can_connect) {
   lldb::ProcessSP process_sp;
-  if (crash_file && !can_connect) {
+  if (crash_file_sp && !can_connect) {
     const size_t header_size = sizeof(llvm::MachO::mach_header);
-    auto data_sp = FileSystem::Instance().CreateDataBuffer(
-        crash_file->GetPath(), header_size, 0);
+    FileSpec file_spec;
+    crash_file_sp->GetFileSpec(file_spec);
+    auto data_sp = FileSystem::Instance().CreateDataBuffer(file_spec.GetPath(),
+                                                           header_size, 0);
     if (data_sp && data_sp->GetByteSize() == header_size) {
       DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
 
@@ -76,7 +79,7 @@ lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
       if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) {
         if (mach_header.filetype == llvm::MachO::MH_CORE)
           process_sp = std::make_shared<ProcessMachCore>(target_sp, listener_sp,
-                                                         *crash_file);
+                                                         crash_file_sp);
       }
     }
   }
@@ -89,12 +92,12 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
     return true;
 
   // For now we are just making sure the file exists for a given module
-  if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
+  if (!m_core_module_sp && FileSystem::Instance().Exists(GetCoreFile())) {
     // Don't add the Target's architecture to the ModuleSpec - we may be
     // working with a core file that doesn't have the correct cpusubtype in the
     // header but we should still try to use it -
     // ModuleSpecList::FindMatchingModuleSpec enforces a strict arch mach.
-    ModuleSpec core_module_spec(m_core_file);
+    ModuleSpec core_module_spec(GetCoreFile());
     Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
                                              nullptr, nullptr, nullptr));
 
@@ -110,9 +113,9 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
 // ProcessMachCore constructor
 ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
                                  ListenerSP listener_sp,
-                                 const FileSpec &core_file)
-    : PostMortemProcess(target_sp, listener_sp), m_core_aranges(),
-      m_core_range_infos(), m_core_module_sp(), m_core_file(core_file),
+                                 lldb::FileSP core_file_sp)
+    : PostMortemProcess(target_sp, listener_sp, core_file_sp), m_core_aranges(),
+      m_core_range_infos(), m_core_module_sp(),
       m_dyld_addr(LLDB_INVALID_ADDRESS),
       m_mach_kernel_addr(LLDB_INVALID_ADDRESS) {}
 
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
index c8820209e3f3830..15d8a30eb2f5fb1 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -22,14 +22,14 @@ class ProcessMachCore : public lldb_private::PostMortemProcess {
 public:
   // Constructors and Destructors
   ProcessMachCore(lldb::TargetSP target_sp, lldb::ListenerSP listener,
-                  const lldb_private::FileSpec &core_file);
+                  lldb::FileSP core_file_sp);
 
   ~ProcessMachCore() override;
 
-  static lldb::ProcessSP
-  CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
-                 const lldb_private::FileSpec *crash_file_path,
-                 bool can_connect);
+  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+                                        lldb::ListenerSP listener,
+                                        lldb::FileSP core_file_sp,
+                                        bool can_connect);
 
   static void Initialize();
 
@@ -130,7 +130,6 @@ class ProcessMachCore : public lldb_private::PostMortemProcess {
   VMRangeToFileOffset m_core_aranges;
   VMRangeToPermissions m_core_range_infos;
   lldb::ModuleSP m_core_module_sp;
-  lldb_private::FileSpec m_core_file;
   lldb::addr_t m_dyld_addr;
   lldb::addr_t m_mach_kernel_addr;
   llvm::StringRef m_dyld_plugin_name;
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 0d5ca42691d3d43..d04d02565a4d15b 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -121,15 +121,17 @@ llvm::StringRef ProcessMinidump::GetPluginDescriptionStatic() {
 
 lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
                                                 lldb::ListenerSP listener_sp,
-                                                const FileSpec *crash_file,
+                                                lldb::FileSP file_sp,
                                                 bool can_connect) {
-  if (!crash_file || can_connect)
+  if (!file_sp || can_connect)
     return nullptr;
 
   lldb::ProcessSP process_sp;
   // Read enough data for the Minidump header
   constexpr size_t header_size = sizeof(Header);
-  auto DataPtr = FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(),
+  const FileSpec file_spec;
+  file_sp->GetFileSpec(const_cast<FileSpec &>(file_spec));
+  auto DataPtr = FileSystem::Instance().CreateDataBuffer(file_spec.GetPath(),
                                                          header_size, 0);
   if (!DataPtr)
     return nullptr;
@@ -139,11 +141,11 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
     return nullptr;
 
   auto AllData =
-      FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), -1, 0);
+      FileSystem::Instance().CreateDataBuffer(file_spec.GetPath(), -1, 0);
   if (!AllData)
     return nullptr;
 
-  return std::make_shared<ProcessMinidump>(target_sp, listener_sp, *crash_file,
+  return std::make_shared<ProcessMinidump>(target_sp, listener_sp, file_sp,
                                            std::move(AllData));
 }
 
@@ -154,9 +156,9 @@ bool ProcessMinidump::CanDebug(lldb::TargetSP target_sp,
 
 ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
                                  lldb::ListenerSP listener_sp,
-                                 const FileSpec &core_file,
+                                 lldb::FileSP core_file_sp,
                                  DataBufferSP core_data)
-    : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file),
+    : PostMortemProcess(target_sp, listener_sp, core_file_sp),
       m_core_data(std::move(core_data)), m_active_exception(nullptr),
       m_is_wow64(false) {}
 
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 0e4e52c0113fb95..73df27e6a778435 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -30,7 +30,7 @@ class ProcessMinidump : public PostMortemProcess {
 public:
   static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
                                         lldb::ListenerSP listener_sp,
-                                        const FileSpec *crash_file_path,
+                                        lldb::FileSP core_file_sp,
                                         bool can_connect);
 
   static void Initialize();
@@ -42,7 +42,7 @@ class ProcessMinidump : public PostMortemProcess {
   static llvm::StringRef GetPluginDescriptionStatic();
 
   ProcessMinidump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
-                  const FileSpec &core_file, lldb::DataBufferSP code_data);
+                  lldb::FileSP core_file_sp, lldb::DataBufferSP code_data);
 
   ~ProcessMinidump() override;
 
@@ -107,7 +107,7 @@ class ProcessMinidump : public PostMortemProcess {
   JITLoaderList &GetJITLoaders() override;
 
 private:
-  FileSpec m_core_file;
+  lldb::FileSP m_core_file_sp;
   lldb::DataBufferSP m_core_data;
   llvm::ArrayRef<minidump::Thread> m_thread_list;
   const minidump::ExceptionStream *m_active_exception;
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index f2a647c1b0bea4c..43043faf362f45f 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -49,7 +49,7 @@ bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) {
 
 lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
                                                 lldb::ListenerSP listener_sp,
-                                                const FileSpec *file,
+                                                lldb::FileSP file_sp,
                                                 bool can_connect) {
   if (!target_sp ||
       !IsScriptLanguageSupported(target_sp->GetDebugger().GetScriptLanguage()))
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
index 0335364b4010b22..4a0fc4ec0f581da 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -24,7 +24,7 @@ class ScriptedProcess : public Process {
 public:
   static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
                                         lldb::ListenerSP listener_sp,
-                                        const FileSpec *crash_file_path,
+                                        lldb::FileSP crash_file_sp,
                                         bool can_connect);
 
   static void Initialize();
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index f82ab05362fbee9..481ee85e646feb9 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -368,8 +368,7 @@ FollowForkMode ProcessProperties::GetFollowForkMode() const {
 
 ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
                               llvm::StringRef plugin_name,
-                              ListenerSP listener_sp,
-                              const FileSpec *crash_file_path,
+                              ListenerSP listener_sp, FileSP crash_file,
                               bool can_connect) {
   static uint32_t g_process_unique_id = 0;
 
@@ -379,7 +378,7 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
     create_callback =
         PluginManager::GetProcessCreateCallbackForPluginName(plugin_name);
     if (create_callback) {
-      process_sp = create_callback(target_sp, listener_sp, crash_file_path,
+      process_sp = create_callback(target_sp, listener_sp, crash_file,
                                    can_connect);
       if (process_sp) {
         if (process_sp->CanDebug(target_sp, true)) {
@@ -393,7 +392,7 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp,
          (create_callback =
               PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr;
          ++idx) {
-      process_sp = create_callback(target_sp, listener_sp, crash_file_path,
+      process_sp = create_callback(target_sp, listener_sp, crash_file,
                                    can_connect);
       if (process_sp) {
         if (process_sp->CanDebug(target_sp, false)) {
diff --git a/lldb/source/Target/ProcessTrace.cpp b/lldb/source/Target/ProcessTrace.cpp
index 061af9e0e520f1c..4ca76f84612d235 100644
--- a/lldb/source/Target/ProcessTrace.cpp
+++ b/lldb/source/Target/ProcessTrace.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Target/ABI.h"
 #include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/Target.h"
+#include "lldb/lldb-forward.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -30,19 +31,19 @@ void ProcessTrace::Terminate() {
 
 ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp,
                                        ListenerSP listener_sp,
-                                       const FileSpec *crash_file,
-                                       bool can_connect) {
+                                       FileSP core_file_sp, bool can_connect) {
   if (can_connect)
     return nullptr;
-  return std::make_shared<ProcessTrace>(target_sp, listener_sp);
+  return std::make_shared<ProcessTrace>(target_sp, listener_sp, core_file_sp);
 }
 
 bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
   return plugin_specified_by_name;
 }
 
-ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp)
-    : PostMortemProcess(target_sp, listener_sp) {}
+ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp,
+                           FileSP core_file_sp)
+    : PostMortemProcess(target_sp, listener_sp, core_file_sp) {}
 
 ProcessTrace::~ProcessTrace() {
   Clear();
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index a6d7148c84e20be..f0020bfe0ecbc00 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -207,7 +207,7 @@ void Target::DeleteCurrentProcess() {
 
 const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp,
                                              llvm::StringRef plugin_name,
-                                             const FileSpec *crash_file,
+                                             FileSP crash_file,
                                              bool can_connect) {
   if (!listener_sp)
     listener_sp = GetDebugger().GetListener();
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index a083fab18eabcbc..894db1c354faf16 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -53,6 +53,11 @@ def test_x86_64(self):
         """Test that lldb can read the process information from an x86_64 linux core file."""
         self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions, "a.out")
 
+    @skipIfLLVMTargetMissing("X86")
+    def test_x86_64_fd(self):
+        """Test that lldb can read the process information from an x86_64 linux core file."""
+        self.do_test_fd("linux-x86_64", self._x86_64_pid, self._x86_64_regions, "a.out")
+
     @skipIfLLVMTargetMissing("SystemZ")
     def test_s390x(self):
         """Test that lldb can read the process information from an s390x linux core file."""
@@ -752,6 +757,17 @@ def do_test(self, filename, pid, region_count, thread_name):
 
         self.dbg.DeleteTarget(target)
 
+    def do_test_fd(self, filename, pid, region_count, thread_name):
+        file_object = open(filename + ".core", "r")
+        fd = file_object.fileno()
+        file = lldb.SBFile(fd, "r", True)
+        target = self.dbg.CreateTarget(filename + ".out")
+        process = target.LoadCore(file)
+
+        self.check_all(process, pid, region_count, thread_name)
+
+        self.dbg.DeleteTarget(target)
+
 
 def replace_path(binary, replace_from, replace_to):
     src = replace_from.encode()
diff --git a/lldb/unittests/Target/LocateModuleCallbackTest.cpp b/lldb/unittests/Target/LocateModuleCallbackTest.cpp
index 0fa0f87efe53ff4..f6da67b6dd2fcc8 100644
--- a/lldb/unittests/Target/LocateModuleCallbackTest.cpp
+++ b/lldb/unittests/Target/LocateModuleCallbackTest.cpp
@@ -184,8 +184,7 @@ void CheckUnstrippedSymbol(const ModuleSP &module_sp) {
 }
 
 ProcessSP MockProcessCreateInstance(TargetSP target_sp, ListenerSP listener_sp,
-                                    const FileSpec *crash_file_path,
-                                    bool can_connect) {
+                                    FileSP crash_file_sp, bool can_connect) {
   return std::make_shared<MockProcess>(target_sp, listener_sp);
 }
 



More information about the lldb-commits mailing list