[Lldb-commits] [lldb] New DynamicLoaderDumpWithModuleList for coredump debugging (PR #149019)
satyanarayana reddy janga via lldb-commits
lldb-commits at lists.llvm.org
Tue Jul 15 21:52:46 PDT 2025
https://github.com/satyajanga created https://github.com/llvm/llvm-project/pull/149019
Summary:
This patch adds a new `DynamicLoaderDumpWithModuleList` plugin which can be used for coredump debugging. It leverages NT_FILE note in coredump to get module list instead of relying on posix rdebug data structure which highly depends on having a matching main executable available. Once the module list is generated a ObjectFilePlaceholder is created for each module.
This feature is only activated by both two conditions are true:
* `use-module-list-dyld` setting is true (false by default)
* coredump having `NT_FILE` notes
Per my testing, Meta's internal modern Linux kernel seems to always generate `NT_FILE` note so this should be very useful.
With this patch, coredump can be changed from
```
lldb <path_to_main_executable> -c <path_to_coredump>
```
to
```
lldb -c <path_to_coredump>
```
Test Plan:
* Added new unit test
Followup PR for `target module replace` command which enables to replace the object file place holders
https://github.com/llvm/llvm-project/pull/148735/
>From 30c14619b06713074423bf879c8d46dbbf5b80a3 Mon Sep 17 00:00:00 2001
From: Jeffrey Tan <jeffreytan at meta.com>
Date: Wed, 21 Jul 2021 13:32:56 -0700
Subject: [PATCH] New DynamicLoaderDumpWithModuleList for coredump debugging
Summary:
This patch adds a new `DynamicLoaderDumpWithModuleList` plugin which can be used for coredump debugging.
It leverages NT_FILE note in coredump to get module list instead of relying on posix rdebug data structure which highly depends on having a matching main executable available. Once the module list is generated a ObjectFilePlaceholder is created for each module.
This feature is only activated by both two conditions are true:
* `use-module-list-dyld` setting is true (false by default)
* coredump having `NT_FILE` notes
Per my testing, Meta's modern Linux kernel seems to always generate `NT_FILE` note so this should be very useful.
With this patch, Meta's internal coredump can be changed from
```
lldb <path_to_main_executable> -c <path_to_coredump>
```
to
```
lldb -c <path_to_coredump>
```
Further diffs involving:
* New `target module replace` command to upgrade PlaceHolder module to real module
* Coredumper side change to generate fbpkg/rpm metadata so that `auto_debuginfo.py` can automatically locate debug info (in review)
* Implement `auto_debuginfo` to parse coredumper metadata to download fbpkg, unzip it, automatically run `target module replace` to upgrade all Placeholder modules into real modules.
I am landing this feature internally first because:
* Unblock the further work listed above
* Early beta testing from our users to get feedback and dogfooding.
* Quick turnover from open source code review
Once we got solid feedback, I will bring this to open source.
Test Plan:
* Added new unit test
* c4crasher end-to-end debugging
Reviewers: wanyi, hyubo, #lldb_team
Reviewed By: wanyi
Subscribers: jimmymalone, frd, #lldb_team
Differential Revision: https://phabricator.intern.facebook.com/D44558615
---
lldb/include/lldb/Core/Debugger.h | 2 +
lldb/include/lldb/Core/LoadedModuleInfoList.h | 11 ++
lldb/source/Core/CoreProperties.td | 4 +
lldb/source/Core/Debugger.cpp | 7 ++
.../Plugins/DynamicLoader/CMakeLists.txt | 1 +
.../ModuleList-DYLD/CMakeLists.txt | 11 ++
.../DynamicLoaderDumpWithModuleList.cpp | 109 ++++++++++++++++++
.../DynamicLoaderDumpWithModuleList.h | 75 ++++++++++++
.../Plugins/Process/elf-core/CMakeLists.txt | 1 +
.../Process/elf-core/ProcessElfCore.cpp | 70 ++++++++---
.../Plugins/Process/elf-core/ProcessElfCore.h | 6 +
11 files changed, 283 insertions(+), 14 deletions(-)
create mode 100644 lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt
create mode 100644 lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp
create mode 100644 lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index 504f936fe317a..e854b731270af 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -247,6 +247,8 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
FormatEntity::Entry GetDisassemblyFormat() const;
+ bool GetUseModuleListDyld() const;
+
FormatEntity::Entry GetFrameFormat() const;
FormatEntity::Entry GetFrameFormatUnique() const;
diff --git a/lldb/include/lldb/Core/LoadedModuleInfoList.h b/lldb/include/lldb/Core/LoadedModuleInfoList.h
index 537a2b0f1d379..5ff62b38d9a9c 100644
--- a/lldb/include/lldb/Core/LoadedModuleInfoList.h
+++ b/lldb/include/lldb/Core/LoadedModuleInfoList.h
@@ -27,6 +27,7 @@ class LoadedModuleInfoList {
e_has_base,
e_has_dynamic,
e_has_link_map,
+ e_has_size,
e_num
};
@@ -77,6 +78,15 @@ class LoadedModuleInfoList {
return m_has[e_has_dynamic];
}
+ void set_size(const lldb::addr_t size) {
+ m_size = size;
+ m_has[e_has_size] = true;
+ }
+ bool get_size(lldb::addr_t &out) const {
+ out = m_size;
+ return m_has[e_has_size];
+ }
+
bool has_info(e_data_point datum) const {
assert(datum < e_num);
return m_has[datum];
@@ -99,6 +109,7 @@ class LoadedModuleInfoList {
lldb::addr_t m_base = LLDB_INVALID_ADDRESS;
bool m_base_is_offset = false;
lldb::addr_t m_dynamic = LLDB_INVALID_ADDRESS;
+ lldb::addr_t m_size = 0;
};
LoadedModuleInfoList() = default;
diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td
index 53dd333f045c9..9aa86efb48bf4 100644
--- a/lldb/source/Core/CoreProperties.td
+++ b/lldb/source/Core/CoreProperties.td
@@ -268,4 +268,8 @@ let Definition = "debugger" in {
Global,
DefaultFalse,
Desc<"Controls whether diagnostics can refer directly to the command input, drawing arrows to it. If false, diagnostics will echo the input.">;
+ def UseModuleListDyld: Property<"use-module-list-dyld", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Use module list dynamic loader plugin for coredump debugging.">;
}
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index ed674ee1275c7..c653a2caf5405 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -295,6 +295,13 @@ bool Debugger::GetAutoConfirm() const {
idx, g_debugger_properties[idx].default_uint_value != 0);
}
+
+bool Debugger::GetUseModuleListDyld() const {
+ const uint32_t idx = ePropertyUseModuleListDyld;
+ return GetPropertyAtIndexAs<bool>(
+ idx, g_debugger_properties[idx].default_uint_value != 0);
+}
+
FormatEntity::Entry Debugger::GetDisassemblyFormat() const {
constexpr uint32_t idx = ePropertyDisassemblyFormat;
return GetPropertyAtIndexAs<FormatEntity::Entry>(idx, {});
diff --git a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt b/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
index 01aba34b94169..6db81b125ed9c 100644
--- a/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
+++ b/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
@@ -8,6 +8,7 @@ set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES
add_subdirectory(Darwin-Kernel)
add_subdirectory(FreeBSD-Kernel)
add_subdirectory(MacOSX-DYLD)
+add_subdirectory(ModuleList-DYLD)
add_subdirectory(POSIX-DYLD)
add_subdirectory(Static)
add_subdirectory(Hexagon-DYLD)
diff --git a/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt
new file mode 100644
index 0000000000000..94d95e3715da1
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginDynamicLoaderDumpWithModuleList PLUGIN
+ DynamicLoaderDumpWithModuleList.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbTarget
+ lldbPluginProcessElfCore
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp
new file mode 100644
index 0000000000000..3337a69ea80e4
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.cpp
@@ -0,0 +1,109 @@
+//===-- DynamicLoaderDumpWithModuleList.cpp-------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Main header include
+#include "DynamicLoaderDumpWithModuleList.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+
+#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE_ADV(DynamicLoaderDumpWithModuleList,
+ DynamicLoaderDumpWithModuleList)
+
+void DynamicLoaderDumpWithModuleList::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void DynamicLoaderDumpWithModuleList::Terminate() {}
+
+llvm::StringRef DynamicLoaderDumpWithModuleList::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in for dumps with module list available";
+}
+
+DynamicLoader *DynamicLoaderDumpWithModuleList::CreateInstance(Process *process,
+ bool force) {
+ // This plug-in is only used when it is requested by name from
+ // ProcessELFCore. ProcessELFCore will look to see if the core
+ // file contains a NT_FILE ELF note, and ask for this plug-in
+ // by name if it does.
+ if (force)
+ return new DynamicLoaderDumpWithModuleList(process);
+ return nullptr;
+}
+
+DynamicLoaderDumpWithModuleList::DynamicLoaderDumpWithModuleList(
+ Process *process)
+ : DynamicLoader(process) {}
+
+DynamicLoaderDumpWithModuleList::~DynamicLoaderDumpWithModuleList() {}
+
+void DynamicLoaderDumpWithModuleList::DidAttach() {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ LLDB_LOGF(log, "DynamicLoaderDumpWithModuleList::%s() pid %" PRIu64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ // Curently only used by ProcessELFCore who will return the results of the
+ // NT_FILE list from ProcessELFCore::GetLoadedModuleList.
+ llvm::Expected<LoadedModuleInfoList> module_info_list_ep =
+ m_process->GetLoadedModuleList();
+ if (!module_info_list_ep) {
+ // TODO: log failure.
+ llvm::consumeError(module_info_list_ep.takeError());
+ return;
+ }
+
+ ModuleList module_list;
+ const LoadedModuleInfoList &module_info_list = *module_info_list_ep;
+ for (const LoadedModuleInfoList::LoadedModuleInfo &modInfo :
+ module_info_list.m_list) {
+ addr_t base_addr, module_size;
+ std::string name;
+ if (!modInfo.get_base(base_addr) || !modInfo.get_name(name) ||
+ !modInfo.get_size(module_size))
+ continue;
+
+ addr_t link_map_addr = 0;
+ FileSpec file(name, m_process->GetTarget().GetArchitecture().GetTriple());
+ const bool base_addr_is_offset = false;
+ ModuleSP module_sp = DynamicLoader::LoadModuleAtAddress(
+ file, link_map_addr, base_addr, base_addr_is_offset);
+ if (module_sp.get()) {
+ LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}", name.c_str());
+ module_list.Append(module_sp);
+ } else {
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ LLDB_LOGF(
+ log,
+ "DynamicLoaderDumpWithModuleList::%s unable to locate the matching "
+ "object file %s, creating a placeholder module at 0x%" PRIx64,
+ __FUNCTION__, name.c_str(), base_addr);
+
+ ModuleSpec module_spec(file, m_process->GetTarget().GetArchitecture());
+ module_sp = Module::CreateModuleFromObjectFile<ObjectFilePlaceholder>(
+ module_spec, base_addr, module_size);
+ UpdateLoadedSections(module_sp, link_map_addr, base_addr,
+ base_addr_is_offset);
+ m_process->GetTarget().GetImages().Append(module_sp, /*notify*/ true);
+ }
+ }
+ m_process->GetTarget().ModulesDidLoad(module_list);
+}
+
+lldb_private::Status DynamicLoaderDumpWithModuleList::CanLoadImage() {
+ return Status();
+}
diff --git a/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h
new file mode 100644
index 0000000000000..30c493bdff999
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h
@@ -0,0 +1,75 @@
+//===-- DynamicLoaderDumpWithModuleList.h --------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MODULELIST_DYLD_DYNAMICLOADERDUMPWITHMODULELIST_H
+#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MODULELIST_DYLD_DYNAMICLOADERDUMPWITHMODULELIST_H
+
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Target/DynamicLoader.h"
+
+/**
+ * Dynamic loader for dump process with module list available.
+ * For example, some coredump files have NT_FILE note section available
+ * so can directly provide the module list without main executable's dynamic
+ * section.
+ */
+class DynamicLoaderDumpWithModuleList : public lldb_private::DynamicLoader {
+public:
+ DynamicLoaderDumpWithModuleList(lldb_private::Process *process);
+
+ ~DynamicLoaderDumpWithModuleList() override;
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() {
+ return "dump-modulelist-dyld";
+ }
+
+ static llvm::StringRef GetPluginDescriptionStatic();
+
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
+
+ // DynamicLoader protocol
+
+ void DidAttach() override;
+
+ void DidLaunch() override {
+ llvm_unreachable(
+ "DynamicLoaderDumpWithModuleList::DidLaunch shouldn't be called");
+ }
+
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override {
+ llvm_unreachable("DynamicLoaderDumpWithModuleList::"
+ "GetStepThroughTrampolinePlan shouldn't be called");
+ }
+
+ lldb_private::Status CanLoadImage() override;
+
+ lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) override {
+ // TODO: how to implement this?
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // PluginInterface protocol
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+private:
+ DynamicLoaderDumpWithModuleList(const DynamicLoaderDumpWithModuleList &) =
+ delete;
+ const DynamicLoaderDumpWithModuleList &
+ operator=(const DynamicLoaderDumpWithModuleList &) = delete;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MODULELIST_DYLD_DYNAMICLOADERDUMPWITHMODULELIST_H
diff --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
index 0bc26bb0efbe3..7c636e88b58f1 100644
--- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
@@ -20,6 +20,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN
LINK_LIBS
lldbCore
lldbTarget
+ lldbPluginDynamicLoaderDumpWithModuleList
lldbPluginDynamicLoaderPosixDYLD
lldbPluginObjectFileELF
lldbPluginProcessUtility
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 88eeddf178788..a0402dde5594a 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -11,6 +11,7 @@
#include <memory>
#include <mutex>
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -28,6 +29,7 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Threading.h"
+#include "Plugins/DynamicLoader/ModuleList-DYLD/DynamicLoaderDumpWithModuleList.h"
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
@@ -295,12 +297,53 @@ UUID ProcessElfCore::FindModuleUUID(const llvm::StringRef path) {
}
lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
- if (m_dyld_up.get() == nullptr)
- m_dyld_up.reset(DynamicLoader::FindPlugin(
- this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic()));
+ if (m_dyld_up.get() == nullptr) {
+ if (GetTarget().GetDebugger().GetUseModuleListDyld()) {
+ llvm::Expected<LoadedModuleInfoList> module_info_list_ep =
+ GetLoadedModuleList();
+ if (module_info_list_ep && !(*module_info_list_ep).m_list.empty())
+ m_dyld_up.reset(DynamicLoader::FindPlugin(
+ this, DynamicLoaderDumpWithModuleList::GetPluginNameStatic()));
+ }
+
+ if (m_dyld_up.get() == nullptr)
+ m_dyld_up.reset(DynamicLoader::FindPlugin(
+ this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic()));
+ }
return m_dyld_up.get();
}
+llvm::Expected<lldb_private::LoadedModuleInfoList>
+ProcessElfCore::GetLoadedModuleList() {
+ if (m_module_info_list.m_list.empty()) {
+ std::unordered_map<std::string, std::pair<lldb::addr_t, lldb::addr_t>>
+ module_range_map;
+ for (const NT_FILE_Entry &file_entry : m_nt_file_entries) {
+ const std::string& module_path = file_entry.path;
+ auto module_iter = module_range_map.find(module_path);
+ if (module_iter == module_range_map.end() ||
+ module_iter->second.first > file_entry.start)
+ module_range_map[module_path] =
+ std::make_pair(file_entry.start, file_entry.end - file_entry.start);
+ else {
+ // Expand module's range to include later sections.
+ auto &module_range = module_range_map[module_path];
+ assert(file_entry.end >= module_range.first);
+ module_range.second = file_entry.end - module_range.first;
+ }
+ }
+
+ for (const auto &module_range_entry : module_range_map) {
+ LoadedModuleInfoList::LoadedModuleInfo module;
+ module.set_name(module_range_entry.first);
+ module.set_base(module_range_entry.second.first);
+ module.set_size(module_range_entry.second.second);
+ m_module_info_list.add(module);
+ }
+ }
+ return m_module_info_list;
+}
+
bool ProcessElfCore::DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) {
const uint32_t num_threads = GetNumThreadContexts();
@@ -406,7 +449,7 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
const lldb::addr_t file_start = address_range->data.GetRangeBase();
const lldb::addr_t file_end = address_range->data.GetRangeEnd();
size_t bytes_to_read = size; // Number of bytes to read from the core file
- size_t bytes_copied = 0; // Number of bytes actually read from the core file
+ size_t bytes_copied = 0; // Number of bytes actually read from the core file
lldb::addr_t bytes_left =
0; // Number of bytes available in the core file from the given address
@@ -489,8 +532,7 @@ lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
static void ParseFreeBSDPrStatus(ThreadData &thread_data,
- const DataExtractor &data,
- bool lp64) {
+ const DataExtractor &data, bool lp64) {
lldb::offset_t offset = 0;
int pr_version = data.GetU32(&offset);
@@ -517,8 +559,7 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data,
// Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details.
static void ParseFreeBSDPrPsInfo(ProcessElfCore &process,
- const DataExtractor &data,
- bool lp64) {
+ const DataExtractor &data, bool lp64) {
lldb::offset_t offset = 0;
int pr_version = data.GetU32(&offset);
@@ -537,8 +578,7 @@ static void ParseFreeBSDPrPsInfo(ProcessElfCore &process,
}
static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data,
- uint32_t &cpi_nlwps,
- uint32_t &cpi_signo,
+ uint32_t &cpi_nlwps, uint32_t &cpi_signo,
uint32_t &cpi_siglwp,
uint32_t &cpi_pid) {
lldb::offset_t offset = 0;
@@ -706,8 +746,8 @@ llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
if (name == "NetBSD-CORE") {
if (note.info.n_type == NETBSD::NT_PROCINFO) {
- llvm::Error error = ParseNetBSDProcInfo(note.data, nlwps, signo,
- siglwp, pr_pid);
+ llvm::Error error =
+ ParseNetBSDProcInfo(note.data, nlwps, signo, siglwp, pr_pid);
if (error)
return error;
SetID(pr_pid);
@@ -933,7 +973,9 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
Status status = prpsinfo.Parse(note.data, arch);
if (status.Fail())
return status.ToError();
- thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname)));
+ thread_data.name.assign(
+ prpsinfo.pr_fname,
+ strnlen(prpsinfo.pr_fname, sizeof(prpsinfo.pr_fname)));
SetID(prpsinfo.pr_pid);
break;
}
@@ -987,7 +1029,7 @@ llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
assert(segment_header.p_type == llvm::ELF::PT_NOTE);
auto notes_or_error = parseSegment(segment_data);
- if(!notes_or_error)
+ if (!notes_or_error)
return notes_or_error.takeError();
switch (GetArchitecture().GetTriple().getOS()) {
case llvm::Triple::FreeBSD:
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index a91c04a277f60..cbfa366e90204 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -19,6 +19,7 @@
#include <list>
#include <vector>
+#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Target/PostMortemProcess.h"
#include "lldb/Utility/Status.h"
@@ -74,6 +75,9 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
// Process Queries
bool IsAlive() override;
+ llvm::Expected<lldb_private::LoadedModuleInfoList>
+ GetLoadedModuleList() override;
+
bool WarnBeforeDetach() const override { return false; }
// Process Memory
@@ -152,6 +156,8 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
// NT_FILE entries found from the NOTE segment
std::vector<NT_FILE_Entry> m_nt_file_entries;
+ lldb_private::LoadedModuleInfoList m_module_info_list;
+
// Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
llvm::Error ParseThreadContextsFromNoteSegment(
const elf::ELFProgramHeader &segment_header,
More information about the lldb-commits
mailing list