Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] [gdb] Work around zero l_addr/l_ld
@ 2026-08-18  7:14 Tom de Vries
  2026-09-02 16:31 ` [PING][RFC] " Tom de Vries
  2026-09-04 13:07 ` [RFC] " Andrew Burgess
  0 siblings, 2 replies; 5+ messages in thread
From: Tom de Vries @ 2026-08-18  7:14 UTC (permalink / raw)
  To: gdb-patches

On ppc64le-linux (AlmaLinux 9.8), I run into:
...
FAIL: gdb.mi/mi-dlmopen.exp: still-in-use fields were all correct
...

While investigating this, I stumbled on this warning emitted during the
calculation of allow_dlmopen_tests:
...
(gdb) run ^M
Starting program: allow_dlmopen_tests.x ^M
[Thread debugging using libthread_db enabled]^M
Using host libthread_db library "/lib64/libthread_db.so.1".^M
warning: .dynamic section for "/lib64/ld64.so.2" is not at the expected \
  address (wrong library or version mismatch?)^M
dlmopen debug supported.^M
...

The warning is mentioned in this glibc commit 88361b408b:
...
    elf: Copy l_addr/l_ld when adding ld.so to a new namespace

    When add ld.so to a new namespace, we don't actually load ld.so.  We
    create a new link map and refers the real one for almost everything.
    Copy l_addr and l_ld from the real ld.so link map to avoid GDB warning:

    warning: .dynamic section for ".../elf/ld-linux-x86-64.so.2" is not at \
      the expected address (wrong library or version mismatch?)

    when handling shared library loaded by dlmopen.
...

So, AFAICT the setup is:
- the glibc package is based on v2.34
- it contains a backport of commit a93d9e03a3 ("Extend struct r_debug to
  support multiple namespaces [BZ #15971]")
- it doesn't contain a backport of commit 88361b408b ("elf: Copy l_addr/l_ld
  when adding ld.so to a new namespace")
- both commits are part of v2.35

What happens is:
- when probing for l_addr and l_ld in svr4_solib_ops::read_lm_info, both get
  the value 0
- in svr4_solib_ops::lm_addr_check, the 0 value propagates to l_dynaddr, and
  "l_addr = l_dynaddr - dynaddr" then underflows, and things go downhill from
  there, resulting in the warning and eventually the FAIL.

Fix this by replicating the missing glibc commit in
svr4_solib_ops::read_lm_info.

I've enabled the fix only for the configuration I can test, for all others I
disabled it using "lmo.l_real_offset = -1".

This is an RFC.  My question is: is the added complexity worth the trouble for
what looks like a cornercase?

[ FTR, in an earlier attempt I proposed to deal with the FAIL using an
xfail [1]. ]

Tested on ppc64le-linux and x86_64-linux.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33662

[1] https://sourceware.org/pipermail/gdb-patches/2026-July/229073.html
---
 gdb/mips-fbsd-tdep.c   |  1 +
 gdb/mips-netbsd-tdep.c |  1 +
 gdb/solib-svr4-linux.c |  6 ++--
 gdb/solib-svr4.c       | 67 +++++++++++++++++++++++++++++++-----------
 gdb/solib-svr4.h       |  4 +++
 5 files changed, 60 insertions(+), 19 deletions(-)

diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index ecad943e8fa..65278937415 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -571,6 +571,7 @@ mips_fbsd_lp64_solib_ops::fetch_link_map_offsets () const
       lmo.l_ld_offset = 24;
       lmo.l_next_offset = 32;
       lmo.l_prev_offset = 40;
+      lmo.l_real_offset = -1;
     }
 
   return lmp;
diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c
index a5bcde20e46..79b1a3cedee 100644
--- a/gdb/mips-netbsd-tdep.c
+++ b/gdb/mips-netbsd-tdep.c
@@ -333,6 +333,7 @@ mips_nbsd_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
       lmo.l_ld_offset = 12;
       lmo.l_next_offset = 16;
       lmo.l_prev_offset = 20;
+      lmo.l_real_offset = -1;
     }
 
   return lmp;
diff --git a/gdb/solib-svr4-linux.c b/gdb/solib-svr4-linux.c
index 2d36adcca73..e67f3036df7 100644
--- a/gdb/solib-svr4-linux.c
+++ b/gdb/solib-svr4-linux.c
@@ -53,6 +53,7 @@ linux_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
       lmo.l_ld_offset = 8;
       lmo.l_next_offset = 12;
       lmo.l_prev_offset = 16;
+      lmo.l_real_offset = -1;
     }
 
   return lmp;
@@ -85,13 +86,14 @@ linux_lp64_svr4_solib_ops::fetch_link_map_offsets () const
       lmo.r_ldsomap_offset = -1;
       lmo.r_next_offset = 40;
 
-      /* Everything we need is in the first 40 bytes.  */
-      lmo.link_map_size = 40;
+      /* Everything we need is in the first 48 bytes.  */
+      lmo.link_map_size = 48;
       lmo.l_addr_offset = 0;
       lmo.l_name_offset = 8;
       lmo.l_ld_offset = 16;
       lmo.l_next_offset = 24;
       lmo.l_prev_offset = 32;
+      lmo.l_real_offset = 40;
     }
 
   return lmp;
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 8e3de4d3ea1..02a20f000d4 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -189,27 +189,58 @@ svr4_solib_ops::read_lm_info (CORE_ADDR lm_addr, CORE_ADDR debug_base) const
   gdb::byte_vector lm (lmo->link_map_size);
 
   if (target_read_memory (lm_addr, lm.data (), lmo->link_map_size) != 0)
-    warning (_("Error reading shared library list entry at %s"),
-	     paddress (current_inferior ()->arch (), lm_addr));
-  else
     {
-      type *ptr_type
-	= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
+      warning (_("Error reading shared library list entry at %s"),
+	       paddress (current_inferior ()->arch (), lm_addr));
+      return lm_info;
+    }
+
+  type *ptr_type
+    = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
+
+  lm_info = std::make_unique<lm_info_svr4> (debug_base);
+  lm_info->lm_addr = lm_addr;
 
-      lm_info = std::make_unique<lm_info_svr4> (debug_base);
-      lm_info->lm_addr = lm_addr;
-
-      lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
-							ptr_type);
-      lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
-      lm_info->l_next = extract_typed_address (&lm[lmo->l_next_offset],
-					       ptr_type);
-      lm_info->l_prev = extract_typed_address (&lm[lmo->l_prev_offset],
-					       ptr_type);
-      lm_info->l_name = extract_typed_address (&lm[lmo->l_name_offset],
-					       ptr_type);
+  lm_info->l_addr_inferior
+    = extract_typed_address (&lm[lmo->l_addr_offset], ptr_type);
+  lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
+  lm_info->l_next = extract_typed_address (&lm[lmo->l_next_offset], ptr_type);
+  lm_info->l_prev = extract_typed_address (&lm[lmo->l_prev_offset], ptr_type);
+  lm_info->l_name = extract_typed_address (&lm[lmo->l_name_offset], ptr_type);
+
+  if (lmo->l_real_offset == -1)
+    return lm_info;
+  CORE_ADDR l_real = extract_typed_address (&lm[lmo->l_real_offset], ptr_type);
+
+  if (l_real == lm_addr)
+    return lm_info;
+
+  /* We have l_real != lm_addr, so l_real points to the link map of ld.so.  */
+
+  if (!(lm_info->l_addr_inferior == 0 && lm_info->l_ld == 0))
+    return lm_info;
+
+  /* We have l_addr_inferior == 0 and l_ld == 0.  This can happen with a glibc
+     that:
+     - has commit a93d9e03a3 ("Extend struct r_debug to support multiple
+       namespaces [BZ #15971]"), but
+     - misses commit 88361b408b ("elf: Copy l_addr/l_ld when adding ld.so to a
+       new namespace").
+     This seems to be the case at least for the alma linux 9.8 BaseOS version,
+     which uses glibc v2.34 and backports only the first commit.
+     Fix / work around this here by replicating the copy of ld_addr/l_ld.  */
+
+  if (target_read_memory (l_real, lm.data (), lmo->link_map_size) != 0)
+    {
+      warning (_("Error reading shared library list entry at %s"),
+	       paddress (current_inferior ()->arch (), l_real));
+      return lm_info;
     }
 
+  lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
+						    ptr_type);
+  lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
+
   return lm_info;
 }
 
@@ -3537,6 +3568,7 @@ ilp32_svr4_solib_ops::fetch_link_map_offsets () const
       lmo.l_ld_offset = 8;
       lmo.l_next_offset = 12;
       lmo.l_prev_offset = 16;
+      lmo.l_real_offset = -1;
     }
 
   return lmp;
@@ -3586,6 +3618,7 @@ lp64_svr4_solib_ops::fetch_link_map_offsets () const
       lmo.l_ld_offset = 16;
       lmo.l_next_offset = 24;
       lmo.l_prev_offset = 32;
+      lmo.l_real_offset = -1;
     }
 
   return lmp;
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
index 3078a092778..83d65842faa 100644
--- a/gdb/solib-svr4.h
+++ b/gdb/solib-svr4.h
@@ -207,6 +207,10 @@ struct link_map_offsets
 
     /* Offset to l_name field in struct link_map.  */
     int l_name_offset;
+
+    /* Offset to l_real field in struct link_map.  Available since glibc
+       version v2.3.4.  */
+    int l_real_offset;
   };
 
 /* Set the gdbarch methods for SVR4 systems.  */

base-commit: e189bfd9b492a0361a37858b9a4709a52a92c803
-- 
2.51.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PING][RFC] [gdb] Work around zero l_addr/l_ld
  2026-08-18  7:14 [RFC] [gdb] Work around zero l_addr/l_ld Tom de Vries
@ 2026-09-02 16:31 ` Tom de Vries
  2026-09-04 13:07 ` [RFC] " Andrew Burgess
  1 sibling, 0 replies; 5+ messages in thread
From: Tom de Vries @ 2026-09-02 16:31 UTC (permalink / raw)
  To: gdb-patches

On 8/18/26 9:14 AM, Tom de Vries wrote:
> On ppc64le-linux (AlmaLinux 9.8), I run into:
> ...
> FAIL: gdb.mi/mi-dlmopen.exp: still-in-use fields were all correct
> ...
> 
> While investigating this, I stumbled on this warning emitted during the
> calculation of allow_dlmopen_tests:
> ...
> (gdb) run ^M
> Starting program: allow_dlmopen_tests.x ^M
> [Thread debugging using libthread_db enabled]^M
> Using host libthread_db library "/lib64/libthread_db.so.1".^M
> warning: .dynamic section for "/lib64/ld64.so.2" is not at the expected \
>    address (wrong library or version mismatch?)^M
> dlmopen debug supported.^M
> ...
> 
> The warning is mentioned in this glibc commit 88361b408b:
> ...
>      elf: Copy l_addr/l_ld when adding ld.so to a new namespace
> 
>      When add ld.so to a new namespace, we don't actually load ld.so.  We
>      create a new link map and refers the real one for almost everything.
>      Copy l_addr and l_ld from the real ld.so link map to avoid GDB warning:
> 
>      warning: .dynamic section for ".../elf/ld-linux-x86-64.so.2" is not at \
>        the expected address (wrong library or version mismatch?)
> 
>      when handling shared library loaded by dlmopen.
> ...
> 
> So, AFAICT the setup is:
> - the glibc package is based on v2.34
> - it contains a backport of commit a93d9e03a3 ("Extend struct r_debug to
>    support multiple namespaces [BZ #15971]")
> - it doesn't contain a backport of commit 88361b408b ("elf: Copy l_addr/l_ld
>    when adding ld.so to a new namespace")
> - both commits are part of v2.35
> 
> What happens is:
> - when probing for l_addr and l_ld in svr4_solib_ops::read_lm_info, both get
>    the value 0
> - in svr4_solib_ops::lm_addr_check, the 0 value propagates to l_dynaddr, and
>    "l_addr = l_dynaddr - dynaddr" then underflows, and things go downhill from
>    there, resulting in the warning and eventually the FAIL.
> 
> Fix this by replicating the missing glibc commit in
> svr4_solib_ops::read_lm_info.
> 
> I've enabled the fix only for the configuration I can test, for all others I
> disabled it using "lmo.l_real_offset = -1".
> 
> This is an RFC.  My question is: is the added complexity worth the trouble for
> what looks like a cornercase?
> 
> [ FTR, in an earlier attempt I proposed to deal with the FAIL using an
> xfail [1]. ]
> 

Ping.

Thanks,
- Tom

> Tested on ppc64le-linux and x86_64-linux.
> 
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33662
> 
> [1] https://sourceware.org/pipermail/gdb-patches/2026-July/229073.html
> ---
>   gdb/mips-fbsd-tdep.c   |  1 +
>   gdb/mips-netbsd-tdep.c |  1 +
>   gdb/solib-svr4-linux.c |  6 ++--
>   gdb/solib-svr4.c       | 67 +++++++++++++++++++++++++++++++-----------
>   gdb/solib-svr4.h       |  4 +++
>   5 files changed, 60 insertions(+), 19 deletions(-)
> 
> diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
> index ecad943e8fa..65278937415 100644
> --- a/gdb/mips-fbsd-tdep.c
> +++ b/gdb/mips-fbsd-tdep.c
> @@ -571,6 +571,7 @@ mips_fbsd_lp64_solib_ops::fetch_link_map_offsets () const
>         lmo.l_ld_offset = 24;
>         lmo.l_next_offset = 32;
>         lmo.l_prev_offset = 40;
> +      lmo.l_real_offset = -1;
>       }
>   
>     return lmp;
> diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c
> index a5bcde20e46..79b1a3cedee 100644
> --- a/gdb/mips-netbsd-tdep.c
> +++ b/gdb/mips-netbsd-tdep.c
> @@ -333,6 +333,7 @@ mips_nbsd_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
>         lmo.l_ld_offset = 12;
>         lmo.l_next_offset = 16;
>         lmo.l_prev_offset = 20;
> +      lmo.l_real_offset = -1;
>       }
>   
>     return lmp;
> diff --git a/gdb/solib-svr4-linux.c b/gdb/solib-svr4-linux.c
> index 2d36adcca73..e67f3036df7 100644
> --- a/gdb/solib-svr4-linux.c
> +++ b/gdb/solib-svr4-linux.c
> @@ -53,6 +53,7 @@ linux_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
>         lmo.l_ld_offset = 8;
>         lmo.l_next_offset = 12;
>         lmo.l_prev_offset = 16;
> +      lmo.l_real_offset = -1;
>       }
>   
>     return lmp;
> @@ -85,13 +86,14 @@ linux_lp64_svr4_solib_ops::fetch_link_map_offsets () const
>         lmo.r_ldsomap_offset = -1;
>         lmo.r_next_offset = 40;
>   
> -      /* Everything we need is in the first 40 bytes.  */
> -      lmo.link_map_size = 40;
> +      /* Everything we need is in the first 48 bytes.  */
> +      lmo.link_map_size = 48;
>         lmo.l_addr_offset = 0;
>         lmo.l_name_offset = 8;
>         lmo.l_ld_offset = 16;
>         lmo.l_next_offset = 24;
>         lmo.l_prev_offset = 32;
> +      lmo.l_real_offset = 40;
>       }
>   
>     return lmp;
> diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
> index 8e3de4d3ea1..02a20f000d4 100644
> --- a/gdb/solib-svr4.c
> +++ b/gdb/solib-svr4.c
> @@ -189,27 +189,58 @@ svr4_solib_ops::read_lm_info (CORE_ADDR lm_addr, CORE_ADDR debug_base) const
>     gdb::byte_vector lm (lmo->link_map_size);
>   
>     if (target_read_memory (lm_addr, lm.data (), lmo->link_map_size) != 0)
> -    warning (_("Error reading shared library list entry at %s"),
> -	     paddress (current_inferior ()->arch (), lm_addr));
> -  else
>       {
> -      type *ptr_type
> -	= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
> +      warning (_("Error reading shared library list entry at %s"),
> +	       paddress (current_inferior ()->arch (), lm_addr));
> +      return lm_info;
> +    }
> +
> +  type *ptr_type
> +    = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
> +
> +  lm_info = std::make_unique<lm_info_svr4> (debug_base);
> +  lm_info->lm_addr = lm_addr;
>   
> -      lm_info = std::make_unique<lm_info_svr4> (debug_base);
> -      lm_info->lm_addr = lm_addr;
> -
> -      lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
> -							ptr_type);
> -      lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
> -      lm_info->l_next = extract_typed_address (&lm[lmo->l_next_offset],
> -					       ptr_type);
> -      lm_info->l_prev = extract_typed_address (&lm[lmo->l_prev_offset],
> -					       ptr_type);
> -      lm_info->l_name = extract_typed_address (&lm[lmo->l_name_offset],
> -					       ptr_type);
> +  lm_info->l_addr_inferior
> +    = extract_typed_address (&lm[lmo->l_addr_offset], ptr_type);
> +  lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
> +  lm_info->l_next = extract_typed_address (&lm[lmo->l_next_offset], ptr_type);
> +  lm_info->l_prev = extract_typed_address (&lm[lmo->l_prev_offset], ptr_type);
> +  lm_info->l_name = extract_typed_address (&lm[lmo->l_name_offset], ptr_type);
> +
> +  if (lmo->l_real_offset == -1)
> +    return lm_info;
> +  CORE_ADDR l_real = extract_typed_address (&lm[lmo->l_real_offset], ptr_type);
> +
> +  if (l_real == lm_addr)
> +    return lm_info;
> +
> +  /* We have l_real != lm_addr, so l_real points to the link map of ld.so.  */
> +
> +  if (!(lm_info->l_addr_inferior == 0 && lm_info->l_ld == 0))
> +    return lm_info;
> +
> +  /* We have l_addr_inferior == 0 and l_ld == 0.  This can happen with a glibc
> +     that:
> +     - has commit a93d9e03a3 ("Extend struct r_debug to support multiple
> +       namespaces [BZ #15971]"), but
> +     - misses commit 88361b408b ("elf: Copy l_addr/l_ld when adding ld.so to a
> +       new namespace").
> +     This seems to be the case at least for the alma linux 9.8 BaseOS version,
> +     which uses glibc v2.34 and backports only the first commit.
> +     Fix / work around this here by replicating the copy of ld_addr/l_ld.  */
> +
> +  if (target_read_memory (l_real, lm.data (), lmo->link_map_size) != 0)
> +    {
> +      warning (_("Error reading shared library list entry at %s"),
> +	       paddress (current_inferior ()->arch (), l_real));
> +      return lm_info;
>       }
>   
> +  lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
> +						    ptr_type);
> +  lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
> +
>     return lm_info;
>   }
>   
> @@ -3537,6 +3568,7 @@ ilp32_svr4_solib_ops::fetch_link_map_offsets () const
>         lmo.l_ld_offset = 8;
>         lmo.l_next_offset = 12;
>         lmo.l_prev_offset = 16;
> +      lmo.l_real_offset = -1;
>       }
>   
>     return lmp;
> @@ -3586,6 +3618,7 @@ lp64_svr4_solib_ops::fetch_link_map_offsets () const
>         lmo.l_ld_offset = 16;
>         lmo.l_next_offset = 24;
>         lmo.l_prev_offset = 32;
> +      lmo.l_real_offset = -1;
>       }
>   
>     return lmp;
> diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
> index 3078a092778..83d65842faa 100644
> --- a/gdb/solib-svr4.h
> +++ b/gdb/solib-svr4.h
> @@ -207,6 +207,10 @@ struct link_map_offsets
>   
>       /* Offset to l_name field in struct link_map.  */
>       int l_name_offset;
> +
> +    /* Offset to l_real field in struct link_map.  Available since glibc
> +       version v2.3.4.  */
> +    int l_real_offset;
>     };
>   
>   /* Set the gdbarch methods for SVR4 systems.  */
> 
> base-commit: e189bfd9b492a0361a37858b9a4709a52a92c803


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC] [gdb] Work around zero l_addr/l_ld
  2026-08-18  7:14 [RFC] [gdb] Work around zero l_addr/l_ld Tom de Vries
  2026-09-02 16:31 ` [PING][RFC] " Tom de Vries
@ 2026-09-04 13:07 ` Andrew Burgess
  2026-09-04 19:44   ` Tom de Vries
  1 sibling, 1 reply; 5+ messages in thread
From: Andrew Burgess @ 2026-09-04 13:07 UTC (permalink / raw)
  To: Tom de Vries, gdb-patches

Tom de Vries <tdevries@suse.de> writes:

> On ppc64le-linux (AlmaLinux 9.8), I run into:
> ...
> FAIL: gdb.mi/mi-dlmopen.exp: still-in-use fields were all correct
> ...
>
> While investigating this, I stumbled on this warning emitted during the
> calculation of allow_dlmopen_tests:
> ...
> (gdb) run ^M
> Starting program: allow_dlmopen_tests.x ^M
> [Thread debugging using libthread_db enabled]^M
> Using host libthread_db library "/lib64/libthread_db.so.1".^M
> warning: .dynamic section for "/lib64/ld64.so.2" is not at the expected \
>   address (wrong library or version mismatch?)^M
> dlmopen debug supported.^M
> ...
>
> The warning is mentioned in this glibc commit 88361b408b:
> ...
>     elf: Copy l_addr/l_ld when adding ld.so to a new namespace
>
>     When add ld.so to a new namespace, we don't actually load ld.so.  We
>     create a new link map and refers the real one for almost everything.
>     Copy l_addr and l_ld from the real ld.so link map to avoid GDB warning:
>
>     warning: .dynamic section for ".../elf/ld-linux-x86-64.so.2" is not at \
>       the expected address (wrong library or version mismatch?)
>
>     when handling shared library loaded by dlmopen.
> ...
>
> So, AFAICT the setup is:
> - the glibc package is based on v2.34
> - it contains a backport of commit a93d9e03a3 ("Extend struct r_debug to
>   support multiple namespaces [BZ #15971]")
> - it doesn't contain a backport of commit 88361b408b ("elf: Copy l_addr/l_ld
>   when adding ld.so to a new namespace")
> - both commits are part of v2.35
>
> What happens is:
> - when probing for l_addr and l_ld in svr4_solib_ops::read_lm_info, both get
>   the value 0
> - in svr4_solib_ops::lm_addr_check, the 0 value propagates to l_dynaddr, and
>   "l_addr = l_dynaddr - dynaddr" then underflows, and things go downhill from
>   there, resulting in the warning and eventually the FAIL.
>
> Fix this by replicating the missing glibc commit in
> svr4_solib_ops::read_lm_info.
>
> I've enabled the fix only for the configuration I can test, for all others I
> disabled it using "lmo.l_real_offset = -1".
>
> This is an RFC.  My question is: is the added complexity worth the trouble for
> what looks like a cornercase?

My take on this would be no, it's not worth the complexity.  It sounds
like the problem is caused by a glibc that has back-ported one part of a
fix, but missed the second part.  I would suggest that a better solution
would be to raise a bug against the downstream glibc port and get them
to back-port the second part of the fix (commit 88361b408b).

Thanks,
Andrew


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC] [gdb] Work around zero l_addr/l_ld
  2026-09-04 13:07 ` [RFC] " Andrew Burgess
@ 2026-09-04 19:44   ` Tom de Vries
  2026-09-11 15:06     ` Tom de Vries
  0 siblings, 1 reply; 5+ messages in thread
From: Tom de Vries @ 2026-09-04 19:44 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

On 9/4/26 3:07 PM, Andrew Burgess wrote:
> Tom de Vries <tdevries@suse.de> writes:
> 
>> On ppc64le-linux (AlmaLinux 9.8), I run into:
>> ...
>> FAIL: gdb.mi/mi-dlmopen.exp: still-in-use fields were all correct
>> ...
>>
>> While investigating this, I stumbled on this warning emitted during the
>> calculation of allow_dlmopen_tests:
>> ...
>> (gdb) run ^M
>> Starting program: allow_dlmopen_tests.x ^M
>> [Thread debugging using libthread_db enabled]^M
>> Using host libthread_db library "/lib64/libthread_db.so.1".^M
>> warning: .dynamic section for "/lib64/ld64.so.2" is not at the expected \
>>    address (wrong library or version mismatch?)^M
>> dlmopen debug supported.^M
>> ...
>>
>> The warning is mentioned in this glibc commit 88361b408b:
>> ...
>>      elf: Copy l_addr/l_ld when adding ld.so to a new namespace
>>
>>      When add ld.so to a new namespace, we don't actually load ld.so.  We
>>      create a new link map and refers the real one for almost everything.
>>      Copy l_addr and l_ld from the real ld.so link map to avoid GDB warning:
>>
>>      warning: .dynamic section for ".../elf/ld-linux-x86-64.so.2" is not at \
>>        the expected address (wrong library or version mismatch?)
>>
>>      when handling shared library loaded by dlmopen.
>> ...
>>
>> So, AFAICT the setup is:
>> - the glibc package is based on v2.34
>> - it contains a backport of commit a93d9e03a3 ("Extend struct r_debug to
>>    support multiple namespaces [BZ #15971]")
>> - it doesn't contain a backport of commit 88361b408b ("elf: Copy l_addr/l_ld
>>    when adding ld.so to a new namespace")
>> - both commits are part of v2.35
>>
>> What happens is:
>> - when probing for l_addr and l_ld in svr4_solib_ops::read_lm_info, both get
>>    the value 0
>> - in svr4_solib_ops::lm_addr_check, the 0 value propagates to l_dynaddr, and
>>    "l_addr = l_dynaddr - dynaddr" then underflows, and things go downhill from
>>    there, resulting in the warning and eventually the FAIL.
>>
>> Fix this by replicating the missing glibc commit in
>> svr4_solib_ops::read_lm_info.
>>
>> I've enabled the fix only for the configuration I can test, for all others I
>> disabled it using "lmo.l_real_offset = -1".
>>
>> This is an RFC.  My question is: is the added complexity worth the trouble for
>> what looks like a cornercase?
> 
> My take on this would be no, it's not worth the complexity.  It sounds
> like the problem is caused by a glibc that has back-ported one part of a
> fix, but missed the second part.  I would suggest that a better solution
> would be to raise a bug against the downstream glibc port and get them
> to back-port the second part of the fix (commit 88361b408b).

Hi Andrew,

thanks for the review.

Your reasoning makes sense, and I can live with it.

I've submitted a bug ( https://bugs.almalinux.org/view.php?id=667 ).

Thanks,
- Tom

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC] [gdb] Work around zero l_addr/l_ld
  2026-09-04 19:44   ` Tom de Vries
@ 2026-09-11 15:06     ` Tom de Vries
  0 siblings, 0 replies; 5+ messages in thread
From: Tom de Vries @ 2026-09-11 15:06 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

On 9/4/26 9:44 PM, Tom de Vries wrote:
>> My take on this would be no, it's not worth the complexity.  It sounds
>> like the problem is caused by a glibc that has back-ported one part of a
>> fix, but missed the second part.  I would suggest that a better solution
>> would be to raise a bug against the downstream glibc port and get them
>> to back-port the second part of the fix (commit 88361b408b).
> 
> Hi Andrew,
> 
> thanks for the review.
> 
> Your reasoning makes sense, and I can live with it.
> 
> I've submitted a bug ( https://bugs.almalinux.org/view.php?id=667 ).

And I've submitted a patch ( 
https://sourceware.org/pipermail/gdb-patches/2026-September/230275.html 
) to detect this situation and bail out.

Thanks,
- Tom

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-09-11 15:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-18  7:14 [RFC] [gdb] Work around zero l_addr/l_ld Tom de Vries
2026-09-02 16:31 ` [PING][RFC] " Tom de Vries
2026-09-04 13:07 ` [RFC] " Andrew Burgess
2026-09-04 19:44   ` Tom de Vries
2026-09-11 15:06     ` Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox