Skip to content

[lldb] Fix ELF core debugging #117070

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 22, 2024
Merged

[lldb] Fix ELF core debugging #117070

merged 1 commit into from
Nov 22, 2024

Conversation

splhack
Copy link
Contributor

@splhack splhack commented Nov 20, 2024

DynamicLoader does not use ProcessElfCore NT_FILE entries to get
UUID. Use GetModuleSpec to get UUID from Process.

@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2024

@llvm/pr-subscribers-lldb

Author: Kazuki Sakamoto (splhack)

Changes

Addressing two issues on ELF core debugging

  1. ProcessElfCore::FindBuidIdInCoreMemory reads wrong address for ELF header (fixed by @clayborg)
  2. DynamicLoader does not use ProcessElfCore NT_FILE entries to get UUID. Add FindBuildId to get UUID from Process.

Full diff: https://github.com/llvm/llvm-project/pull/117070.diff

5 Files Affected:

  • (modified) lldb/include/lldb/Target/Process.h (+2)
  • (modified) lldb/source/Core/DynamicLoader.cpp (+4)
  • (modified) lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp (+9-1)
  • (modified) lldb/source/Plugins/Process/elf-core/ProcessElfCore.h (+3)
  • (modified) lldb/source/Target/Process.cpp (+5)
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index b8c53a474ba6b9..2f0cf78f260c5a 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1380,6 +1380,8 @@ class Process : public std::enable_shared_from_this<Process>,
 
   virtual bool GetProcessInfo(ProcessInstanceInfo &info);
 
+  virtual lldb_private::UUID FindBuildId(const llvm::StringRef path);
+
   /// Get the exit status for a process.
   ///
   /// \return
diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp
index 68d6ab0850853f..cc396e92721123 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -157,6 +157,10 @@ DynamicLoader::GetSectionListFromModule(const ModuleSP module) const {
 ModuleSP DynamicLoader::FindModuleViaTarget(const FileSpec &file) {
   Target &target = m_process->GetTarget();
   ModuleSpec module_spec(file, target.GetArchitecture());
+  if (UUID uuid = m_process->FindBuildId(file.GetPath())) {
+    // Process may have the UUID for the module, e.g. ELF core.
+    module_spec.GetUUID().SetFromStringRef(uuid.GetAsString());
+  }
 
   if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec))
     return module_sp;
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 7955594bf5d94c..8ad6b83d77effe 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -281,6 +281,13 @@ void ProcessElfCore::UpdateBuildIdForNTFileEntries() {
   }
 }
 
+UUID ProcessElfCore::FindBuildId(const llvm::StringRef path) {
+  for (NT_FILE_Entry &entry : m_nt_file_entries)
+    if (path == entry.path)
+      return entry.uuid;
+  return UUID();
+}
+
 lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() {
   if (m_dyld_up.get() == nullptr)
     m_dyld_up.reset(DynamicLoader::FindPlugin(
@@ -1034,7 +1041,8 @@ UUID ProcessElfCore::FindBuidIdInCoreMemory(lldb::addr_t address) {
     std::vector<uint8_t> note_bytes;
     note_bytes.resize(program_header.p_memsz);
 
-    byte_read = ReadMemory(program_header.p_vaddr, note_bytes.data(),
+    const lldb::addr_t program_header_vaddr = program_header.p_vaddr + address;
+    byte_read = ReadMemory(program_header_vaddr, note_bytes.data(),
                            program_header.p_memsz, error);
     if (byte_read != program_header.p_memsz)
       continue;
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index 280c61ed376396..303f18249a976e 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -97,6 +97,9 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
 
   bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;
 
+  // Returns the gnu uuid from matched NT_FILE entry
+  lldb_private::UUID FindBuildId(const llvm::StringRef path) override;
+
 protected:
   void Clear();
 
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 9125ceca74a003..d2921f623bbefc 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -6080,6 +6080,11 @@ bool Process::GetProcessInfo(ProcessInstanceInfo &info) {
   return platform_sp->GetProcessInfo(GetID(), info);
 }
 
+lldb_private::UUID Process::FindBuildId(const llvm::StringRef path) {
+  lldb_private::UUID invalid_uuid;
+  return invalid_uuid;
+}
+
 ThreadCollectionSP Process::GetHistoryThreads(lldb::addr_t addr) {
   ThreadCollectionSP threads;
 

@cs01
Copy link

cs01 commented Nov 20, 2024

Thank you! Are there any unit tests that can exercise this?

Or at least repro steps to generate a core with the elf headers in case any one wants to manually test.

@clayborg
Copy link
Collaborator

The reading of build IDs is tracked in this PR: #117028

@splhack
Copy link
Contributor Author

splhack commented Nov 20, 2024

The reading of build IDs is tracked in this PR: #117028

will rebase onto #117028

Copy link

github-actions bot commented Nov 21, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@splhack splhack force-pushed the main branch 2 times, most recently from 8d33354 to b934783 Compare November 22, 2024 04:02
if (module_file_spec.GetPath() == entry.path) {
module_spec.GetFileSpec() = module_file_spec;
module_spec.GetArchitecture() = arch;
module_spec.GetUUID().SetFromStringRef(entry.uuid.GetAsString());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to:

module_spec.GetUUID() = entry.uuid;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

DynamicLoader does not use ProcessElfCore NT_FILE entries to get
UUID. Use GetModuleSpec to get UUID from Process.
@splhack splhack merged commit 1290e95 into llvm:main Nov 22, 2024
7 checks passed
@vvereschaka
Copy link
Contributor

Hi @splhack ,

looks like these changes break lldb-api::TestLoadUnload.py test on the LLDB remote-linux builders:

@splhack
Copy link
Contributor Author

splhack commented Nov 23, 2024

@vvereschaka let me check

@splhack
Copy link
Contributor Author

splhack commented Nov 23, 2024

@clayborg most likely calling GetModuleSpec is the cause of these failures.
ProcessGDBRemote fetches modules from remote.
FindBuildId does not have the issue. What do you think?

looks like these changes break lldb-api::TestLoadUnload.py test on the LLDB remote-linux builders:

splhack added a commit that referenced this pull request Nov 24, 2024
ELF core debugging fix #117070 broke TestLoadUnload.py tests due to
GetModuleSpec call, ProcessGDBRemote fetches modules from remote. Revise
the original PR, renamed FindBuildId to FindModuleUUID.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants