https://github.com/GeorgeHuyubo updated https://github.com/llvm/llvm-project/pull/157170
>From 056abe4ebed7c2e08728e0dda20374e32292ff0c Mon Sep 17 00:00:00 2001 From: George Hu <hy...@meta.com> Date: Fri, 5 Sep 2025 13:23:48 -0700 Subject: [PATCH] [lldb][ElfCore] Improve main executable detection in core files --- clang/tools/clang-format/git-clang-format | 2 +- .../Process/elf-core/ProcessElfCore.cpp | 41 +++++++++++++------ .../Plugins/Process/elf-core/ProcessElfCore.h | 10 +++++ 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/clang/tools/clang-format/git-clang-format b/clang/tools/clang-format/git-clang-format index fe2dd283d403e..e9133bd52a158 100755 --- a/clang/tools/clang-format/git-clang-format +++ b/clang/tools/clang-format/git-clang-format @@ -482,7 +482,7 @@ def filter_symlinks(dictionary): def filter_ignored_files(dictionary, binary): """Delete every key in `dictionary` that is ignored by clang-format.""" - ignored_files = run(binary, "-list-ignored", *dictionary.keys()) + ignored_files = run(binary) if not ignored_files: return ignored_files = ignored_files.split("\n") diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 88eeddf178788..a6331619a835a 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, core_file) {} + : PostMortemProcess(target_sp, listener_sp, core_file), m_uuids() {} // Destructor ProcessElfCore::~ProcessElfCore() { @@ -257,12 +257,12 @@ Status ProcessElfCore::DoLoadCore() { // the main executable using data we found in the core file notes. lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); if (!exe_module_sp) { - // The first entry in the NT_FILE might be our executable if (!m_nt_file_entries.empty()) { + llvm::StringRef executable_path = GetMainExecutablePath(); ModuleSpec exe_module_spec; exe_module_spec.GetArchitecture() = arch; - exe_module_spec.GetUUID() = m_nt_file_entries[0].uuid; - exe_module_spec.GetFileSpec().SetFile(m_nt_file_entries[0].path, + exe_module_spec.GetUUID() = FindModuleUUID(executable_path); + exe_module_spec.GetFileSpec().SetFile(executable_path, FileSpec::Style::native); if (exe_module_spec.GetFileSpec()) { exe_module_sp = @@ -277,20 +277,36 @@ Status ProcessElfCore::DoLoadCore() { void ProcessElfCore::UpdateBuildIdForNTFileEntries() { Log *log = GetLog(LLDBLog::Process); + m_uuids.clear(); for (NT_FILE_Entry &entry : m_nt_file_entries) { entry.uuid = FindBuidIdInCoreMemory(entry.start); - if (log && entry.uuid.IsValid()) - LLDB_LOGF(log, "%s found UUID @ %16.16" PRIx64 ": %s \"%s\"", - __FUNCTION__, entry.start, entry.uuid.GetAsString().c_str(), - entry.path.c_str()); + if (entry.uuid.IsValid()) { + m_uuids[entry.path] = entry.uuid; + if (log) + LLDB_LOGF(log, "%s found UUID @ %16.16" PRIx64 ": %s \"%s\"", + __FUNCTION__, entry.start, entry.uuid.GetAsString().c_str(), + entry.path.c_str()); + } } } +llvm::StringRef ProcessElfCore::GetMainExecutablePath() { + // The first entry in the NT_FILE might be our executable + llvm::StringRef executable_path = m_nt_file_entries[0].path; + // Prefer the NT_FILE entry matching m_executable_name as main executable. + for (const NT_FILE_Entry &file_entry : m_nt_file_entries) + if (llvm::StringRef(file_entry.path).ends_with("/" + m_executable_name)) { + executable_path = file_entry.path; + break; + } + return executable_path; +} + UUID ProcessElfCore::FindModuleUUID(const llvm::StringRef path) { - // Returns the gnu uuid from matched NT_FILE entry - for (NT_FILE_Entry &entry : m_nt_file_entries) - if (path == entry.path && entry.uuid.IsValid()) - return entry.uuid; + // Look up UUID in the map for fast access + auto it = m_uuids.find(path); + if (it != m_uuids.end()) + return it->second; return UUID(); } @@ -935,6 +951,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { return status.ToError(); thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname))); SetID(prpsinfo.pr_pid); + m_executable_name = prpsinfo.pr_fname; break; } case ELF::NT_SIGINFO: { diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index a91c04a277f60..e73d80cd1c8c4 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -17,6 +17,7 @@ #define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_PROCESSELFCORE_H #include <list> +#include <unordered_map> #include <vector> #include "lldb/Target/PostMortemProcess.h" @@ -152,6 +153,12 @@ class ProcessElfCore : public lldb_private::PostMortemProcess { // NT_FILE entries found from the NOTE segment std::vector<NT_FILE_Entry> m_nt_file_entries; + // Map from file path to UUID for quick lookup + std::unordered_map<llvm::StringRef, lldb_private::UUID> m_uuids; + + // Executable name found from the ELF PRPSINFO + std::string m_executable_name; + // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment llvm::Error ParseThreadContextsFromNoteSegment( const elf::ELFProgramHeader &segment_header, @@ -165,6 +172,9 @@ class ProcessElfCore : public lldb_private::PostMortemProcess { lldb_private::UUID FindModuleUUID(const llvm::StringRef path) override; + // Returns the main executable path + llvm::StringRef GetMainExecutablePath(); + // Returns the value of certain type of note of a given start address lldb_private::UUID FindBuidIdInCoreMemory(lldb::addr_t address); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits