public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Thiago Jung Bauermann <bauerman@br.ibm.com>
To: gdb@sourceware.org
Subject: GDB hangs with simple multi-threaded program on linux
Date: Thu, 15 Jul 2010 15:46:00 -0000	[thread overview]
Message-ID: <1279208729.14577.21.camel@hactar> (raw)

Hi,

I'm struggling with an issue which perhaps you already faced or thought
about...

The following testcase locks GDB nearly every time on Linux:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define NUM_THREADS     2

pthread_t main_thread;

void *print_hello (void *threadid)
{
   int tid = (int) threadid;

   printf ("Hello world! It's me, thread #%d!\n", tid);

   /* The first thread will wait main terminate.  */
   if (tid == 0)
     pthread_join (main_thread, NULL);

   pthread_exit (NULL);
}

int main (int argc, char *argv[])
{
   int i, rc;
   pthread_t threads[NUM_THREADS];

   main_thread = pthread_self ();

   for (i = 0; i < NUM_THREADS; i++) {
      printf ("In main: creating thread %d\n", i);

      rc = pthread_create (&threads[i], NULL, print_hello, (void *) i);
      if (rc) {
         printf ("ERROR; return code from pthread_create is %d\n", rc);
         exit (-1);
      }
   }

   pthread_exit (NULL);
}

What's special about this testcase is that the main thread exits earlier
than the threads it creates.

What GDB does is that when it is notified about a signal in some thread,
it will send a SIGSTOP to the other threads in the process and then call
waitpid on them to make sure that the threads indeed stopped (at the end
of linux_nat_wait_1, when it call stop_callback and stop_wait_callback
on all LWPs).

Normally this is ok, but what is happening here is that when GDB is
notified about a signal in some thread, the main thread already exited
(but GDB is oblivious to this fact), and GDB sends a SIGSTOP to every
thread in the debuggee (including the zombie main thread) and then when
it goes on to wait on them threads, it hangs while waiting on the main
thread.

I suspect that waitpid interprets the call to wait on the main thread to
actually mean waiting on the whole program instead (since TID == PID in
this case) and hangs because there are other threads in the thread group
(even though they are in the tracing stop state).

So my questions are:

1. Is it true that when the main thread exits but there are other
threads in the thread group, then no SIGCHLD is generated to notify GDB
that it exited (perhaps because such a SIGCHLD could be ambiguous and
mean that the whole process exited)? If so, how can GDB learn when the
main thread exits? This is why GDB still thinks the main thread is still
around. Either that, or GDB missed the SIGCHLD or it is later in the
queue and yet unprocessed.

2. Is there a way for GDB to wait on just the main thread instead of on
the whole process when it waits on a TID which is also the PID?

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center

             reply	other threads:[~2010-07-15 15:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-15 15:46 Thiago Jung Bauermann [this message]
2010-07-15 18:44 ` Tom Tromey
2010-07-15 18:47   ` Tom Tromey
2010-07-15 22:22   ` Thiago Jung Bauermann
2010-07-16 15:58   ` Daniel Jacobowitz

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=1279208729.14577.21.camel@hactar \
    --to=bauerman@br.ibm.com \
    --cc=gdb@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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).