From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Subject: [PING][RFC] [gdb] Work around zero l_addr/l_ld
Date: Wed, 2 Sep 2026 18:31:16 +0200 [thread overview]
Message-ID: <1abe3b5a-6f3a-4112-9338-3892c8863ceb@suse.de> (raw)
In-Reply-To: <20260818071434.2121734-1-tdevries@suse.de>
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
next prev parent reply other threads:[~2026-09-02 16:31 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 7:14 [RFC] " Tom de Vries
2026-09-02 16:31 ` Tom de Vries [this message]
2026-09-04 13:07 ` Andrew Burgess
2026-09-04 19:44 ` Tom de Vries
2026-09-11 15:06 ` Tom de Vries
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1abe3b5a-6f3a-4112-9338-3892c8863ceb@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox