Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: Simon Marchi <simark@simark.ca>, gdb-patches@sourceware.org
Subject: Re: [PATCH v2] [gdb] Detect corrupt link map with zero l_ld and l_addr
Date: Mon, 28 Sep 2026 17:30:39 +0200	[thread overview]
Message-ID: <1fac98af-e3d1-47ba-a0b6-c97344bfe6c9@suse.de> (raw)
In-Reply-To: <b3a3f05b-35f2-43ab-9292-711706c1eea3@simark.ca>

On 9/28/26 4:54 PM, Simon Marchi wrote:
> On 9/27/26 2:30 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") [1]
>> - 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 detecting the situation in svr4_solib_ops::read_so_list, and
>> bailing out with a warning.
>>
>> Add detection of this and other "corruption" warnings in allow_dlmopen_tests
>> to make sure the related test-cases are skipped.
>>
>> In more detail, before this patch we have:
>> ...
>> $ gdb -q -batch outputs/gdb.base/dlmopen/dlmopen -ex start -ex next \
>>      -ex "pipe info shared | ld64"
>>    ...
>> warning: .dynamic section for "/lib64/ld64.so.2" is not at the expected \
>>    address (wrong library or version mismatch?)
>>    ...
>> 0x00007ffff7f80000  0x00007ffff8000000  0         Yes         /lib64/ld64.so.2
>> 0x0000000000000160  0xffffffffffff0000  1         Yes         /lib64/ld64.so.2
>> ...
>> and after:
>> ...
>> warning: Corrupted shared library entry: zero l_addr and l_ld
>> warning: Corrupted shared library entry: zero l_addr and l_ld
>>    ...
>> 0x00007ffff7f80000  0x00007ffff8000000  0         Yes         /lib64/ld64.so.2
>> ...
>>
>> Alternatively, we could prevent the underflow in svr4_solib_ops::lm_addr_check:
>> ...
>>    bool l_addr_updated = false;
>>    if (l_dynaddr >= dynaddr)
>>      {
>>        l_addr = l_dynaddr - dynaddr;
>>        l_addr_updated = true;
>>      }
>>
>>    if (l_addr_updated
>>        && (l_addr & (minpagesize - 1)) == 0
>>        && (l_addr & align) == ((l_dynaddr - dynaddr) & align))
>> ...
>> but we'd still get an incorrect range:
>> ...
>> warning: .dynamic section for "/lib64/ld64.so.2" is not at the expected \
>>    address (wrong library or version mismatch?)
>>    ...
>> 0x00007ffff7f80000  0x00007ffff8000000  0         Yes         /lib64/ld64.so.2
>> 0x0000000000060000  0x0000000000080000  1         Yes         /lib64/ld64.so.2
>> ...
>>
>> FTR, in an earlier attempt I proposed to deal with the FAIL using an
>> xfail [2].  And in an another attempt I proposed to deal with it by
>> replicating the glibc fix in gdb [3].
>>
>> Changed in v2:
>> - fixed incorrect footnote reference
>> - made comment more precise
>> - use "AlmaLinux" consistently
>>
>> Versions:
>> - v1 https://sourceware.org/pipermail/gdb-patches/2026-September/230275.html
>>
>> Tested on ppc64le-linux and x86_64-linux.
>>
>> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33662
>>
>> [1] https://bugs.almalinux.org/view.php?id=667
>> [2] https://sourceware.org/pipermail/gdb-patches/2026-July/229073.html
>> [3] https://sourceware.org/pipermail/gdb-patches/2026-August/229549.html
>> ---
>>   gdb/solib-svr4.c          | 23 +++++++++++++++++++++++
>>   gdb/testsuite/lib/gdb.exp |  3 +++
>>   2 files changed, 26 insertions(+)
>>
>> diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
>> index c4af1b11a4d..810b0fae7a3 100644
>> --- a/gdb/solib-svr4.c
>> +++ b/gdb/solib-svr4.c
>> @@ -1333,6 +1333,29 @@ svr4_solib_ops::read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
>>         if (*name == '\0' || match_main (name.get ()))
>>   	continue;
>>   
>> +      gdb_byte dummy;
>> +      if (li->l_addr_inferior == 0 && li->l_ld == 0
>> +	  && target_read_memory (0, &dummy, 1) != 0)
>> +	{
>> +	  /* We have l_addr_inferior == 0 and l_ld == 0 (corresponding to link
>> +	     map entries l_addr and l_ld).  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 AlmaLinux 9.8 BaseOS
>> +	     version, which uses glibc v2.34 and backports only the first
>> +	     commit ( https://bugs.almalinux.org/view.php?id=667 ).
>> +	     Detect this here and bail out.  Otherwise, we'll present
>> +	     the user with incorrect info for "info shared".
>> +
>> +	     The target_read_memory is there to detect the improbable
>> +	     situation that address 0 is mapped, in which case it might be the
>> +	     address of the dynamic section.  */
>> +	  warning (_("Corrupted shared library entry: zero l_addr and l_ld"));
>> +	  return 0;
>> +	}
> 
> Returning 0 means we stop reading the shared library list, is that
> expected?  The known case of this isn't really that the shared library
> list is corrupted, just that this entry is incomplete.  We could maybe
> skip over this entry and keep reading the list, to be able to present
> all the loaded shared libraries to the user?
> 

Hi Simon,

thanks for the review.

I think you're right, using continue instead of return 0 is more 
appropriate.

> Is the warning printed every time the library list is read (like at each
> stop)?  Does that become annoying for the user?
> 
> In the end maybe we don't care too much about these concerns, because
> it's for one specific version of one specific distro, and only when
> debugging programs that use multiple namespaces (which are quite rare I
> think).
> 

It could be annoying, agreed.

I'm treating this though as a corruption that is triggered by one 
specific version of one specific distro, but might happen otherwise.

So I think there is information in how many times the warning triggers.

We could keep track for which shared libs the warning triggers, and emit 
a summary instead.  But I don't think it's worth the bother at this point.

Thanks,
- Tom

> Simon


      reply	other threads:[~2026-09-28 15:31 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-27  6:30 Tom de Vries
2026-09-28 14:54 ` Simon Marchi
2026-09-28 15:30   ` Tom de Vries [this message]

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=1fac98af-e3d1-47ba-a0b6-c97344bfe6c9@suse.de \
    --to=tdevries@suse.de \
    --cc=gdb-patches@sourceware.org \
    --cc=simark@simark.ca \
    /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