https://github.com/jeffreytan81 updated https://github.com/llvm/llvm-project/pull/80767
>From e7af15ff3c1bdd42799b25f76145b8a19739eea5 Mon Sep 17 00:00:00 2001 From: jeffreytan81 <jeffrey...@fb.com> Date: Mon, 5 Feb 2024 15:58:23 -0800 Subject: [PATCH 1/3] Add a new SBProcess:: GetCoreFile() API --- lldb/include/lldb/API/SBProcess.h | 7 +++++++ lldb/include/lldb/Target/PostMortemProcess.h | 9 ++++++++ lldb/include/lldb/Target/Process.h | 7 +++++++ lldb/include/lldb/Target/ProcessTrace.h | 3 ++- lldb/source/API/SBProcess.cpp | 11 ++++++++++ .../FreeBSDKernel/ProcessFreeBSDKernel.cpp | 21 +++++++++++-------- .../FreeBSDKernel/ProcessFreeBSDKernel.h | 3 ++- .../Process/elf-core/ProcessElfCore.cpp | 8 +++---- .../Plugins/Process/elf-core/ProcessElfCore.h | 1 - .../Process/mach-core/ProcessMachCore.cpp | 6 +++--- .../Process/mach-core/ProcessMachCore.h | 1 - .../Process/minidump/ProcessMinidump.cpp | 2 +- .../Process/minidump/ProcessMinidump.h | 1 - lldb/source/Target/ProcessTrace.cpp | 7 ++++--- .../postmortem/elf-core/TestLinuxCore.py | 11 ++++++++++ 15 files changed, 73 insertions(+), 25 deletions(-) diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 8c1c81418f83d..13994ed300853 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -398,6 +398,13 @@ class LLDB_API SBProcess { /// valid. lldb::SBProcessInfo GetProcessInfo(); + /// Return target dump file during postmortem debugging. + /// An empty file will be returned for live debugging. + /// + /// \return + /// The target dump file spec. + lldb::SBFileSpec GetCoreFile(); + /// Allocate memory within the process. /// /// This function will allocate memory in the process's address space. diff --git a/lldb/include/lldb/Target/PostMortemProcess.h b/lldb/include/lldb/Target/PostMortemProcess.h index 7207fc99ef29a..9c9cd7fa599bc 100644 --- a/lldb/include/lldb/Target/PostMortemProcess.h +++ b/lldb/include/lldb/Target/PostMortemProcess.h @@ -24,7 +24,16 @@ class PostMortemProcess : public Process { using Process::Process; public: + PostMortemProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, + const FileSpec &core_file) + : Process(target_sp, listener_sp), m_core_file(core_file) {} + bool IsLiveDebugSession() const override { return false; } + + FileSpec GetCoreFile() const override { return m_core_file; } + +protected: + FileSpec m_core_file; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 7048921d6034f..0ad626ffd3613 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1503,6 +1503,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 true. + /// + /// \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 037dea232cc02..7a025100f6803 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, + const FileSpec &core_file); ~ProcessTrace() override; diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index 4864ea0e7d026..a9fe915324683 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -1244,6 +1244,17 @@ lldb::SBProcessInfo SBProcess::GetProcessInfo() { return sb_proc_info; } +lldb::SBFileSpec SBProcess::GetCoreFile() { + LLDB_INSTRUMENT_VA(this); + + ProcessSP process_sp(GetSP()); + FileSpec core_file; + if (process_sp) { + core_file = process_sp->GetCoreFile(); + } + return SBFileSpec(core_file); +} + lldb::addr_t SBProcess::AllocateMemory(size_t size, uint32_t permissions, lldb::SBError &sb_error) { LLDB_INSTRUMENT_VA(this, size, permissions, sb_error); diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp index 601f5df43dbba..997b590851103 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); + fvc_t *fvc, const FileSpec &core_file); ~ProcessFreeBSDKernelFVC(); @@ -67,8 +67,9 @@ class ProcessFreeBSDKernelKVM : public ProcessFreeBSDKernel { } // namespace ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp, - ListenerSP listener_sp) - : PostMortemProcess(target_sp, listener_sp) {} + ListenerSP listener_sp, + const FileSpec &core_file) + : PostMortemProcess(target_sp, listener_sp, core_file) {} lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp, ListenerSP listener_sp, @@ -82,7 +83,7 @@ lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp, crash_file->GetPath().c_str(), nullptr, nullptr, nullptr); if (fvc) return std::make_shared<ProcessFreeBSDKernelFVC>(target_sp, listener_sp, - fvc); + fvc, *crash_file); #endif #if defined(__FreeBSD__) @@ -91,7 +92,7 @@ lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp, crash_file->GetPath().c_str(), O_RDONLY, nullptr, nullptr); if (kvm) return std::make_shared<ProcessFreeBSDKernelKVM>(target_sp, listener_sp, - kvm); + kvm, *crash_file); #endif } return nullptr; @@ -276,8 +277,9 @@ lldb::addr_t ProcessFreeBSDKernel::FindSymbol(const char *name) { ProcessFreeBSDKernelFVC::ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp, ListenerSP listener_sp, - fvc_t *fvc) - : ProcessFreeBSDKernel(target_sp, listener_sp), m_fvc(fvc) {} + fvc_t *fvc, + const FileSpec &core_file) + : ProcessFreeBSDKernel(target_sp, listener_sp, crash_file), m_fvc(fvc) {} ProcessFreeBSDKernelFVC::~ProcessFreeBSDKernelFVC() { if (m_fvc) @@ -303,8 +305,9 @@ const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); } ProcessFreeBSDKernelKVM::ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp, ListenerSP listener_sp, - kvm_t *fvc) - : ProcessFreeBSDKernel(target_sp, listener_sp), m_kvm(fvc) {} + kvm_t *fvc, + const FileSpec &core_file) + : ProcessFreeBSDKernel(target_sp, listener_sp, core_file), 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 5bd463126307c..06c9d062441e5 100644 --- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h +++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h @@ -13,7 +13,8 @@ class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess { public: - ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener); + ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener, + const lldb_private::FileSpec &core_file); static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener, diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 7723009787f7f..fbd0a4be40c06 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -99,7 +99,7 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file) - : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file) {} + : PostMortemProcess(target_sp, listener_sp, core_file) {} // Destructor ProcessElfCore::~ProcessElfCore() { @@ -224,7 +224,7 @@ Status ProcessElfCore::DoLoadCore() { ArchSpec core_arch(m_core_module_sp->GetArchitecture()); target_arch.MergeFrom(core_arch); GetTarget().SetArchitecture(target_arch); - + SetUnixSignals(UnixSignals::Create(GetArchitecture())); // Ensure we found at least one thread that was stopped on a signal. @@ -261,7 +261,7 @@ Status ProcessElfCore::DoLoadCore() { exe_module_spec.GetFileSpec().SetFile(m_nt_file_entries[0].path, FileSpec::Style::native); if (exe_module_spec.GetFileSpec()) { - exe_module_sp = GetTarget().GetOrCreateModule(exe_module_spec, + exe_module_sp = GetTarget().GetOrCreateModule(exe_module_spec, true /* notify */); if (exe_module_sp) GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo); @@ -865,7 +865,7 @@ llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) { /// - NT_SIGINFO - Information about the signal that terminated the process /// - NT_AUXV - Process auxiliary vector /// - NT_FILE - Files mapped into memory -/// +/// /// Additionally, for each thread in the process the core file will contain at /// least the NT_PRSTATUS note, containing the thread id and general purpose /// registers. It may include additional notes for other register sets (floating diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 1454e8735a677..2cec635bbacfe 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -127,7 +127,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/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index a2ea19388b75f..ead35b47694e0 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -111,8 +111,8 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp, 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), + : PostMortemProcess(target_sp, listener_sp, core_file), m_core_aranges(), + m_core_range_infos(), m_core_module_sp(), m_dyld_addr(LLDB_INVALID_ADDRESS), m_mach_kernel_addr(LLDB_INVALID_ADDRESS) {} @@ -404,7 +404,7 @@ bool ProcessMachCore::LoadBinariesViaMetadata() { // LoadCoreFileImges may have set the dynamic loader, e.g. in // PlatformDarwinKernel::LoadPlatformBinaryAndSetup(). - // If we now have a dynamic loader, save its name so we don't + // If we now have a dynamic loader, save its name so we don't // un-set it later. if (m_dyld_up) m_dyld_plugin_name = GetDynamicLoader()->GetPluginName(); diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h index c8820209e3f38..8996ae116614b 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h @@ -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 b72307c7e4b96..13599f4a1553f 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -156,7 +156,7 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file, DataBufferSP core_data) - : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file), + : PostMortemProcess(target_sp, listener_sp, core_file), 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 0e4e52c0113fb..3f3123a0a8b5d 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -107,7 +107,6 @@ class ProcessMinidump : public PostMortemProcess { JITLoaderList &GetJITLoaders() override; private: - FileSpec m_core_file; lldb::DataBufferSP m_core_data; llvm::ArrayRef<minidump::Thread> m_thread_list; const minidump::ExceptionStream *m_active_exception; diff --git a/lldb/source/Target/ProcessTrace.cpp b/lldb/source/Target/ProcessTrace.cpp index 3a41f257627c2..4718a7ca50a7c 100644 --- a/lldb/source/Target/ProcessTrace.cpp +++ b/lldb/source/Target/ProcessTrace.cpp @@ -36,15 +36,16 @@ ProcessSP ProcessTrace::CreateInstance(TargetSP target_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, *crash_file); } 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, + const FileSpec &core_file) + : PostMortemProcess(target_sp, listener_sp, core_file) {} ProcessTrace::~ProcessTrace() { Clear(); diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py index d6907075820ec..7ec5e0d7c8309 100644 --- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -633,6 +633,17 @@ def test_arm_core(self): self.expect("register read --all") + def test_get_core_file_api(self): + """ + Test SBProcess::GetCoreFile() API can successfully get the core file. + """ + core_file_name = "linux-x86_64.core" + target = self.dbg.CreateTarget("linux-x86_64.out") + process = target.LoadCore(core_file_name) + self.assertTrue(process, PROCESS_IS_VALID) + self.assertEqual(process.GetCoreFile().GetFilename(), core_file_name) + self.dbg.DeleteTarget(target) + def check_memory_regions(self, process, region_count): region_list = process.GetMemoryRegions() self.assertEqual(region_list.GetSize(), region_count) >From 1143405dc568f8ff473fd834dd8a738c372b65e3 Mon Sep 17 00:00:00 2001 From: jeffreytan81 <jeffrey...@fb.com> Date: Mon, 5 Feb 2024 17:13:34 -0800 Subject: [PATCH 2/3] Address feedback and fix formatter --- lldb/include/lldb/API/SBProcess.h | 8 +++++--- lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp | 8 ++++---- lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 13994ed300853..4f92a41f3028a 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -398,11 +398,13 @@ class LLDB_API SBProcess { /// valid. lldb::SBProcessInfo GetProcessInfo(); - /// Return target dump file during postmortem debugging. - /// An empty file will be returned for live debugging. + /// Get the file specification for the core file that is currently being used + /// for the process. If the process is not loaded from a core file, then an + /// invalid file specification will be returned. /// /// \return - /// The target dump file spec. + /// The path to the core file for this target or an invalid file spec if + /// the process isn't loaded from a core file. lldb::SBFileSpec GetCoreFile(); /// Allocate memory within the process. diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index fbd0a4be40c06..1730b7aa19249 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -224,7 +224,7 @@ Status ProcessElfCore::DoLoadCore() { ArchSpec core_arch(m_core_module_sp->GetArchitecture()); target_arch.MergeFrom(core_arch); GetTarget().SetArchitecture(target_arch); - + SetUnixSignals(UnixSignals::Create(GetArchitecture())); // Ensure we found at least one thread that was stopped on a signal. @@ -261,8 +261,8 @@ Status ProcessElfCore::DoLoadCore() { exe_module_spec.GetFileSpec().SetFile(m_nt_file_entries[0].path, FileSpec::Style::native); if (exe_module_spec.GetFileSpec()) { - exe_module_sp = GetTarget().GetOrCreateModule(exe_module_spec, - true /* notify */); + exe_module_sp = + GetTarget().GetOrCreateModule(exe_module_spec, true /* notify */); if (exe_module_sp) GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo); } @@ -865,7 +865,7 @@ llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) { /// - NT_SIGINFO - Information about the signal that terminated the process /// - NT_AUXV - Process auxiliary vector /// - NT_FILE - Files mapped into memory -/// +/// /// Additionally, for each thread in the process the core file will contain at /// least the NT_PRSTATUS note, containing the thread id and general purpose /// registers. It may include additional notes for other register sets (floating diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index ead35b47694e0..3961dcf0fbcc0 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -404,7 +404,7 @@ bool ProcessMachCore::LoadBinariesViaMetadata() { // LoadCoreFileImges may have set the dynamic loader, e.g. in // PlatformDarwinKernel::LoadPlatformBinaryAndSetup(). - // If we now have a dynamic loader, save its name so we don't + // If we now have a dynamic loader, save its name so we don't // un-set it later. if (m_dyld_up) m_dyld_plugin_name = GetDynamicLoader()->GetPluginName(); >From 1ac666e37e4c2043f521be0815808bf96d2ce9d2 Mon Sep 17 00:00:00 2001 From: jeffreytan81 <jeffrey...@fb.com> Date: Mon, 5 Feb 2024 17:15:02 -0800 Subject: [PATCH 3/3] Remove one extra space --- lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 1730b7aa19249..36812c27a5b6d 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -224,7 +224,7 @@ Status ProcessElfCore::DoLoadCore() { ArchSpec core_arch(m_core_module_sp->GetArchitecture()); target_arch.MergeFrom(core_arch); GetTarget().SetArchitecture(target_arch); - + SetUnixSignals(UnixSignals::Create(GetArchitecture())); // Ensure we found at least one thread that was stopped on a signal. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits