[Lldb-commits] [lldb] [lldb] Check for duplicate interpreter modules without loading them (PR #69932)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 23 08:02:33 PDT 2023


https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/69932

Fixes #68987

Early on we load the interpreter (most commonly ld-linux) in LoadInterpreterModule. Then later when we get the first DYLD rendezvous we get a list of libraries that commonly includes ld-linux again.

Previously we would load this duplicate, see that it was a duplicate, and unload it.

Problem was that this unloaded the section information of the first copy of ld-linux. On platforms where you can place a breakpoint using only an address, this wasn't an issue.

On ARM you have ARM and Thumb modes. We must know which one the section we're breaking in is, otherwise we'll go there in the wrong mode and SIGILL. This happened on ARM when lldb tried to call mmap during expression evaluation.

To fix this, I am making the assumption that the base address we see in the module prior to loading can be compared with what we know the interpreter base address is. Then we don't have to load the module to know we can ignore it.

This fixes the lldb test suite on Ubuntu versions where https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/1927192 has been fixed. Which was recently done on Jammy.

>From b82be6da03cc7a38ad8dbc0e27508cbbd3a4000a Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Fri, 20 Oct 2023 10:56:30 +0000
Subject: [PATCH] [lldb] Check for duplicate interpreter modules without
 loading them

Fixes #68987

Early on we load the interpreter (most commonly ld-linux) in
LoadInterpreterModule. Then later when we get the first DYLD
rendezvous we get a list of libraries that commonly includes ld-linux
again.

Previously we would load this duplicate, see that it was a duplicate,
and unload it.

Problem was that this unloaded the section information of the first
copy of ld-linux. On platforms where you can place a breakpoint
using only an address, this wasn't an issue.

On ARM you have ARM and Thumb modes. We must know which one the section
we're breaking in is, otherwise we'll go there in the wrong mode and SIGILL.
This happened on ARM when lldb tried to call mmap during expression
evaluation.

To fix this, I am making the assumption that the base address we see
in the module prior to loading can be compared with what we know
the interpreter base address is. Then we don't have to load the
module to know we can ignore it.

This fixes the lldb test suite on Ubuntu versions where
https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/1927192 has been fixed.
Which was recently done on Jammy.
---
 .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp       | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index c427b476089e458..3d65f496742099d 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -437,6 +437,14 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
       m_initial_modules_added = true;
     }
     for (; I != E; ++I) {
+      // Don't load a duplicate copy of ld.so if we have already loaded it
+      // earlier in LoadInterpreterModule. If we instead loaded then unloaded it
+      // later, the section information for ld.so would be removed. That
+      // information is required for placing breakpoints on Arm/Thumb systems.
+      if ((m_interpreter_module.lock() != nullptr) &&
+          (I->base_addr == m_interpreter_base))
+        continue;
+
       ModuleSP module_sp =
           LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
       if (!module_sp.get())
@@ -450,15 +458,6 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
         } else if (module_sp == interpreter_sp) {
           // Module already loaded.
           continue;
-        } else {
-          // If this is a duplicate instance of ld.so, unload it.  We may end
-          // up with it if we load it via a different path than before
-          // (symlink vs real path).
-          // TODO: remove this once we either fix library matching or avoid
-          // loading the interpreter when setting the rendezvous breakpoint.
-          UnloadSections(module_sp);
-          loaded_modules.Remove(module_sp);
-          continue;
         }
       }
 



More information about the lldb-commits mailing list