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 <huyubo...@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); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits