Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: Simon Marchi <simon.marchi@polymtl.ca>, gdb-patches@sourceware.org
Subject: Re: [PATCH][gdb/testsuite] Fix check-libthread-db.exp FAILs with glibc 2.33
Date: Tue, 13 Jul 2021 14:59:09 +0200	[thread overview]
Message-ID: <b948648e-be02-4883-d21a-0358dce61b93@suse.de> (raw)
In-Reply-To: <2421785c-a5b9-64b7-371c-0abf35a4cb63@polymtl.ca>

On 7/13/21 6:49 AM, Simon Marchi wrote:
> 
> 
> On 2021-07-07 10:09 a.m., Tom de Vries wrote:
>> Hi,
>>
>> When running test-case gdb.threads/check-libthread-db.exp on openSUSE
>> Tumbleweed with glibc 2.33, I get:
>> ...
>> (gdb) maint check libthread-db^M
>> Running libthread_db integrity checks:^M
>>   Got thread 0x7ffff7c79b80 => 9354 => 0x7ffff7c79b80; errno = 0 ... OK^M
>> libthread_db integrity checks passed.^M
>> (gdb) FAIL: gdb.threads/check-libthread-db.exp: user-initiated check: libpthread.so not initialized (pattern 2)
>> ...
>>
>> The test-case expects instead:
>> ...
>>   Got thread 0x0 => 9354 => 0x0 ... OK^M
>> ...
>> which is what I get on openSUSE Leap 15.2 with glibc 2.26, and what is
>> described in the test-case like this:
>> ...
>>     # libthread_db should fake a single thread with th_unique == NULL.
>> ...
>>
>> Using a breakpoint on check_thread_db_callback we can compare the two
>> scenarios, and find that in the latter case we hit this code in glibc function
>> iterate_thread_list in nptl_db/td_ta_thr_iter.c:
>> ...
>>   if (next == 0 && fake_empty)
>>     {
>>       /* __pthread_initialize_minimal has not run.  There is just the main
>>          thread to return.  We cannot rely on its thread register.  They
>>          sometimes contain garbage that would confuse us, left by the
>>          kernel at exec.  So if it looks like initialization is incomplete,
>>          we only fake a special descriptor for the initial thread.  */
>>       td_thrhandle_t th = { ta, 0 };
>>       return callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK;
>>     }
>> ...
>> while in the former case we don't because this preceding statement doesn't
>> result in next == 0:
>> ...
>>   err = DB_GET_FIELD (next, ta, head, list_t, next, 0);
>> ...
>>
>> Note that the comment mentions __pthread_initialize_minimal, but in both cases
>> it has already run before we hit the callback, so it's possible the comment is
>> no longer accurate.
>>
>> Anyway, the results do not look wrong, so fix this by updating the regexp
>> patterns to agree with what libthread-db is telling us.
>>
>> Tested on x86_64-linux, both with glibc 2.33 and 2.26.
>>
>> Any comments?
> 
> I got a bit lost in the glibc code, but I am wondering if this change in
> behavior might have been caused by this glibc change:
> 
>   https://gitlab.com/gnutools/glibc/-/commit/1daccf403b1bd86370eb94edca794dc106d02039
> 

It is, I've bisect the change in behavior to precisely that commit.

> Before this, the stack_user list was global variables.  This is one of
> the two lists that get walked to enumerate the threads.  Since it isn't
> initialized statically, it got placed in .bss and is zeroed-out by
> default, hence why thread-db expected to read next == 0, I guess.
> 
> Or, it may be that the moment that this nptl minimal initialization is
> done has changed, at least relative to where we do our checks.  It looks
> like __pthread_initialize_minimal_internal is called as a constructor.
> Has it always been this way?  By the time we stop on the solib load
> event, have the constructors of the lib ran?
> 

Before the commit, we have:

1. Initial event, hitting _dl_debug_state:
...
Stopped due to shared library event (no libraries added or removed)
...

2. Loading some libs:
...
[Thread debugging using libthread_db enabled]
Using host libthread_db library
"/home/vries/glibc/build/nptl_db/libthread_db.so.1".
Stopped due to shared library event:
  Inferior loaded /home/vries/glibc/build/nptl/libpthread.so.0
    /home/vries/glibc/build/math/libm.so.6
    /home/vries/glibc/build/libc.so.6
...

3. __pthread_initialize_minimal_internal entry, at which point we still
have null __stack_user:
...
Continuing.

Breakpoint 1, __pthread_initialize_minimal_internal () at nptl-init.c:227
227     {
(gdb) p __stack_user
$2 = {next = 0x0, prev = 0x0}
...

4. __pthread_initialize_minimal_internal exit, at which point we have
initialized stack_user:
...
(gdb) fin
Run till exit from #0  __pthread_initialize_minimal_internal () at
nptl-init.c:227
_init () at ../sysdeps/x86_64/crtn.S:40
40              addq $8, %rsp
(gdb) p __stack_user
$3 = {next = 0x7ffff7ff2e40, prev = 0x7ffff7ff2e40}
...

After the commit:

1. Initial event, hitting _dl_debug_state:
...
Stopped due to shared library event (no libraries added or removed)
...

2. We hit this list_add which adds the main thread to dl_stack_user:
...
(gdb) up
#1  init_tls (naudit=naudit@entry=0) at rtld.c:804
804       list_add (&THREAD_SELF->list, &GL (dl_stack_user));
...

3. Loading some libs:
...
(gdb) c
Continuing.
[Thread debugging using libthread_db enabled]
Using host libthread_db library
"/home/vries/glibc/build/nptl_db/libthread_db.so.1".
Stopped due to shared library event:
  Inferior loaded /home/vries/glibc/build/nptl/libpthread.so.0
    /home/vries/glibc/build/math/libm.so.6
    /home/vries/glibc/build/libc.so.6
...

4. __pthread_initialize_minimal_internal entry:
...
Continuing.

Breakpoint 2, __pthread_initialize_minimal_internal () at nptl-init.c:227
227     {
...

So, it doesn't look like the moment when
__pthread_initialize_minimal_internal is called changed, just the
location of where stack_user is initialized.

I'll try to update the log message a bit and resubmit.

Thanks,
- Tom

> In any case, I agree that this looks benign, the regexp checks we have
> exactly one thread.  But I would still be curious to know the real
> reason for the change in behavior.
> 
> Simon
> 

  reply	other threads:[~2021-07-13 12:59 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-07 14:09 Tom de Vries
2021-07-13  4:49 ` Simon Marchi via Gdb-patches
2021-07-13 12:59   ` Tom de Vries [this message]
2021-07-13 13:15     ` Tom de Vries
2021-07-13 13:31       ` Simon Marchi via Gdb-patches

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=b948648e-be02-4883-d21a-0358dce61b93@suse.de \
    --to=tdevries@suse.de \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@polymtl.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