Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Daniel, thread vs. fork question.
@ 2004-03-11  1:08 Michael Snyder
  2004-03-19  0:09 ` Daniel Jacobowitz
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Michael Snyder @ 2004-03-11  1:08 UTC (permalink / raw)
  To: Daniel Jacobowitz, gdb-patches

Hey Daniel,

Got a question concerning the code in 
linux-nat.c::linux_handle_extended_wait.

You've got a PTRACE_EVENT_FORK event, and now you're going to call 
waitpid.  You pull a pid out of a list of stopped pids, and wait for
it using waitpid.  In your comment, you explain that you don't have to
worry about the pid being a clone, because you didn't ask for pids in
the event mask.

But how is this affected by threads, especially NPTL threads?
I've got a fairly simple test-case (modified from pthreads.c,
I'll attach it), in which a child thread calls fork -- but gdb
apparently tries to wait on the main thread (or perhaps the most
recent event thread).  Since that's not the thread that called
fork, waitpid returns -1 with "no child".  Gdb reports:
	waiting for new child: No child processes.

FWIW, I've tried this on both a single-processor and an SMP machine.

Michael




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

* Re: Daniel, thread vs. fork question.
  2004-03-19  0:09 ` Daniel Jacobowitz
@ 2004-03-11  1:51   ` Daniel Jacobowitz
  2004-03-19  0:09   ` Michael Snyder
  1 sibling, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2004-03-11  1:51 UTC (permalink / raw)
  To: Michael Snyder; +Cc: gdb-patches

On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
> Hey Daniel,
> 
> Got a question concerning the code in 
> linux-nat.c::linux_handle_extended_wait.
> 
> You've got a PTRACE_EVENT_FORK event, and now you're going to call 
> waitpid.  You pull a pid out of a list of stopped pids, and wait for
> it using waitpid.  In your comment, you explain that you don't have to
> worry about the pid being a clone, because you didn't ask for pids in
> the event mask.
> 
> But how is this affected by threads, especially NPTL threads?
> I've got a fairly simple test-case (modified from pthreads.c,
> I'll attach it), in which a child thread calls fork -- but gdb
> apparently tries to wait on the main thread (or perhaps the most
> recent event thread).  Since that's not the thread that called
> fork, waitpid returns -1 with "no child".  Gdb reports:
> 	waiting for new child: No child processes.
> 
> FWIW, I've tried this on both a single-processor and an SMP machine.

No attachment?  Also, what glibc/nptl version are you using.

It's entirely possible that I didn't handle some threaded case.  But we
save the PID that we plan to wait on, which should be the child thread,
so I don't see how what you're describing can happn.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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

* Re: Daniel, thread vs. fork question.
  2004-03-19  0:09   ` Michael Snyder
@ 2004-03-11  2:22     ` Michael Snyder
  2004-03-19 19:29     ` Michael Snyder
  1 sibling, 0 replies; 11+ messages in thread
From: Michael Snyder @ 2004-03-11  2:22 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]

Daniel Jacobowitz wrote:
> On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
> 
>>Hey Daniel,
>>
>>Got a question concerning the code in 
>>linux-nat.c::linux_handle_extended_wait.
>>
>>You've got a PTRACE_EVENT_FORK event, and now you're going to call 
>>waitpid.  You pull a pid out of a list of stopped pids, and wait for
>>it using waitpid.  In your comment, you explain that you don't have to
>>worry about the pid being a clone, because you didn't ask for pids in
>>the event mask.
>>
>>But how is this affected by threads, especially NPTL threads?
>>I've got a fairly simple test-case (modified from pthreads.c,
>>I'll attach it), in which a child thread calls fork -- but gdb
>>apparently tries to wait on the main thread (or perhaps the most
>>recent event thread).  Since that's not the thread that called
>>fork, waitpid returns -1 with "no child".  Gdb reports:
>>	waiting for new child: No child processes.
>>
>>FWIW, I've tried this on both a single-processor and an SMP machine.
> 
> 
> No attachment? 

Argh.  Inevitable, isn't it?  See currently attached.

 > Also, what glibc/nptl version are you using.

Well, it's RHEL3, so I believe it's glibc 2.3 and nptl
(not sure what version of nptl).

> It's entirely possible that I didn't handle some threaded case.  But we
> save the PID that we plan to wait on, which should be the child thread,
> so I don't see how what you're describing can happn.

It's repeatable, on at least 3 machines.  Let me know (now that I've
actually provided the test case) if you can't reproduce it.


[-- Attachment #2: pthreads.c --]
[-- Type: text/plain, Size: 4410 bytes --]

/* Pthreads test program.
   Copyright 1996, 2002, 2003
   Free Software Foundation, Inc.

   Written by Fred Fish of Cygnus Support
   Contributed by Cygnus Support

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

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

/* Under OSF 2.0 & 3.0 and HPUX 10, the second arg of pthread_create
   is prototyped to be just a "pthread_attr_t", while under Solaris it
   is a "pthread_attr_t *".  Arg! */

#if defined (__osf__) || defined (__hpux__)
#define PTHREAD_CREATE_ARG2(arg) arg
#define PTHREAD_CREATE_NULL_ARG2 null_attr
static pthread_attr_t null_attr;
#else
#define PTHREAD_CREATE_ARG2(arg) &arg
#define PTHREAD_CREATE_NULL_ARG2 NULL
#endif

static int verbose = 0;

static void
common_routine (arg)
     int arg;
{
  static int from_thread1;
  static int from_thread2;
  static int from_main;
  static int hits;
  static int full_coverage;

  if (verbose) printf("common_routine (%d)\n", arg);
  hits++;
  switch (arg)
    {
    case 0:
      from_main++;
      break;
    case 1:
      from_thread1++;
      break;
    case 2:
      from_thread2++;
      break;
    }
  if (from_main && from_thread1 && from_thread2)
    full_coverage = 1;
}

static void *
thread1 (void *arg)
{
  int i;
  int z = 0;

  if (verbose) printf ("thread1 (%0x) ; pid = %d\n", arg, getpid ());
  for (i=1; i <= 10000000; i++)
    {
      if (verbose) printf("thread1 %d\n", pthread_self ());
      z += i;
      common_routine (1);
      sleep(1);
    }
  return (void *) 0;
}

static void *
thread2 (void * arg)
{
  int i;
  int k = 0;

  if (verbose) printf ("thread2 (%0x) ; pid = %d\n", arg, getpid ());
  for (i=1; i <= 10000000; i++)
    {
      if (verbose) printf("thread2 %d\n", pthread_self ());
      k += i;
      common_routine (2);
      sleep(1);
    }
  sleep(100);
  return (void *) 0;
}

static void *
forkthread (void *arg)
{
  int pid = fork ();
  int ret = 0, status = 0;

  switch (pid) {
  case 0:	/* child */
    printf ("I'm the child, my pid = %d\n", getpid ());
    break;
  case -1:	/* Parent, failed to create child */
  default:	/* Parent, fork succeeded.  */
    printf ("I'm the parent, mypid = %d, fork returned %d\n",
	    getpid (), pid);
    if (pid == -1)
      perror ("fork failed: ");
    else
      waitpid (pid, &status, 0);
  }
}

void
foo (a, b, c)
     int a, b, c;
{
  int d, e, f;

  if (verbose) printf("a=%d\n", a);
}

main(argc, argv)
     int argc;
     char **argv;
{
  pthread_t tid1, tid2, forktid;
  int j;
  int t = 0;
  void (*xxx) ();
  pthread_attr_t attr;

  if (verbose) printf ("pid = %d\n", getpid());

  foo (1, 2, 3);

#ifndef __osf__
  if (pthread_attr_init (&attr))
    {
      perror ("pthread_attr_init 1");
      exit (1);
    }
#endif

#ifdef PTHREAD_SCOPE_SYSTEM
  if (pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM))
    {
      perror ("pthread_attr_setscope 1");
      exit (1);
    }
#endif

  if (pthread_create (&tid1, PTHREAD_CREATE_ARG2(attr), thread1, (void *) 0xfeedface))
    {
      perror ("pthread_create 1");
      exit (1);
    }
  if (verbose) printf ("Made thread %d\n", tid1);
  sleep (1);

  if (pthread_create (&tid2, PTHREAD_CREATE_NULL_ARG2, thread2, (void *) 0xdeadbeef))
    {
      perror ("pthread_create 2");
      exit (1);
    }
  if (verbose) printf("Made thread %d\n", tid2);
  sleep (1);

  if (pthread_create (&forktid, PTHREAD_CREATE_NULL_ARG2, forkthread, (void *) 0xdeadbeef))
    {
      perror ("pthread_create 3 (fork)");
      exit (1);
    }
  if (verbose) printf("Made thread %d\n", tid2);

  for (j = 1; j <= 10000000; j++)
    {
      if (verbose) printf("top %d\n", pthread_self ());
      common_routine (0);
      sleep(1);
      t += j;
    }
  
  exit(0);
}


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

* Re: Daniel, thread vs. fork question.
  2004-03-19  0:09 ` Daniel Jacobowitz
  2004-03-11  1:51   ` Daniel Jacobowitz
@ 2004-03-19  0:09   ` Michael Snyder
  2004-03-11  2:22     ` Michael Snyder
  2004-03-19 19:29     ` Michael Snyder
  1 sibling, 2 replies; 11+ messages in thread
From: Michael Snyder @ 2004-03-19  0:09 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]

Daniel Jacobowitz wrote:
> On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
> 
>>Hey Daniel,
>>
>>Got a question concerning the code in 
>>linux-nat.c::linux_handle_extended_wait.
>>
>>You've got a PTRACE_EVENT_FORK event, and now you're going to call 
>>waitpid.  You pull a pid out of a list of stopped pids, and wait for
>>it using waitpid.  In your comment, you explain that you don't have to
>>worry about the pid being a clone, because you didn't ask for pids in
>>the event mask.
>>
>>But how is this affected by threads, especially NPTL threads?
>>I've got a fairly simple test-case (modified from pthreads.c,
>>I'll attach it), in which a child thread calls fork -- but gdb
>>apparently tries to wait on the main thread (or perhaps the most
>>recent event thread).  Since that's not the thread that called
>>fork, waitpid returns -1 with "no child".  Gdb reports:
>>	waiting for new child: No child processes.
>>
>>FWIW, I've tried this on both a single-processor and an SMP machine.
> 
> 
> No attachment? 

Argh.  Inevitable, isn't it?  See currently attached.

 > Also, what glibc/nptl version are you using.

Well, it's RHEL3, so I believe it's glibc 2.3 and nptl
(not sure what version of nptl).

> It's entirely possible that I didn't handle some threaded case.  But we
> save the PID that we plan to wait on, which should be the child thread,
> so I don't see how what you're describing can happn.

It's repeatable, on at least 3 machines.  Let me know (now that I've
actually provided the test case) if you can't reproduce it.


[-- Attachment #2: pthreads.c --]
[-- Type: text/plain, Size: 4410 bytes --]

/* Pthreads test program.
   Copyright 1996, 2002, 2003
   Free Software Foundation, Inc.

   Written by Fred Fish of Cygnus Support
   Contributed by Cygnus Support

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

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

/* Under OSF 2.0 & 3.0 and HPUX 10, the second arg of pthread_create
   is prototyped to be just a "pthread_attr_t", while under Solaris it
   is a "pthread_attr_t *".  Arg! */

#if defined (__osf__) || defined (__hpux__)
#define PTHREAD_CREATE_ARG2(arg) arg
#define PTHREAD_CREATE_NULL_ARG2 null_attr
static pthread_attr_t null_attr;
#else
#define PTHREAD_CREATE_ARG2(arg) &arg
#define PTHREAD_CREATE_NULL_ARG2 NULL
#endif

static int verbose = 0;

static void
common_routine (arg)
     int arg;
{
  static int from_thread1;
  static int from_thread2;
  static int from_main;
  static int hits;
  static int full_coverage;

  if (verbose) printf("common_routine (%d)\n", arg);
  hits++;
  switch (arg)
    {
    case 0:
      from_main++;
      break;
    case 1:
      from_thread1++;
      break;
    case 2:
      from_thread2++;
      break;
    }
  if (from_main && from_thread1 && from_thread2)
    full_coverage = 1;
}

static void *
thread1 (void *arg)
{
  int i;
  int z = 0;

  if (verbose) printf ("thread1 (%0x) ; pid = %d\n", arg, getpid ());
  for (i=1; i <= 10000000; i++)
    {
      if (verbose) printf("thread1 %d\n", pthread_self ());
      z += i;
      common_routine (1);
      sleep(1);
    }
  return (void *) 0;
}

static void *
thread2 (void * arg)
{
  int i;
  int k = 0;

  if (verbose) printf ("thread2 (%0x) ; pid = %d\n", arg, getpid ());
  for (i=1; i <= 10000000; i++)
    {
      if (verbose) printf("thread2 %d\n", pthread_self ());
      k += i;
      common_routine (2);
      sleep(1);
    }
  sleep(100);
  return (void *) 0;
}

static void *
forkthread (void *arg)
{
  int pid = fork ();
  int ret = 0, status = 0;

  switch (pid) {
  case 0:	/* child */
    printf ("I'm the child, my pid = %d\n", getpid ());
    break;
  case -1:	/* Parent, failed to create child */
  default:	/* Parent, fork succeeded.  */
    printf ("I'm the parent, mypid = %d, fork returned %d\n",
	    getpid (), pid);
    if (pid == -1)
      perror ("fork failed: ");
    else
      waitpid (pid, &status, 0);
  }
}

void
foo (a, b, c)
     int a, b, c;
{
  int d, e, f;

  if (verbose) printf("a=%d\n", a);
}

main(argc, argv)
     int argc;
     char **argv;
{
  pthread_t tid1, tid2, forktid;
  int j;
  int t = 0;
  void (*xxx) ();
  pthread_attr_t attr;

  if (verbose) printf ("pid = %d\n", getpid());

  foo (1, 2, 3);

#ifndef __osf__
  if (pthread_attr_init (&attr))
    {
      perror ("pthread_attr_init 1");
      exit (1);
    }
#endif

#ifdef PTHREAD_SCOPE_SYSTEM
  if (pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM))
    {
      perror ("pthread_attr_setscope 1");
      exit (1);
    }
#endif

  if (pthread_create (&tid1, PTHREAD_CREATE_ARG2(attr), thread1, (void *) 0xfeedface))
    {
      perror ("pthread_create 1");
      exit (1);
    }
  if (verbose) printf ("Made thread %d\n", tid1);
  sleep (1);

  if (pthread_create (&tid2, PTHREAD_CREATE_NULL_ARG2, thread2, (void *) 0xdeadbeef))
    {
      perror ("pthread_create 2");
      exit (1);
    }
  if (verbose) printf("Made thread %d\n", tid2);
  sleep (1);

  if (pthread_create (&forktid, PTHREAD_CREATE_NULL_ARG2, forkthread, (void *) 0xdeadbeef))
    {
      perror ("pthread_create 3 (fork)");
      exit (1);
    }
  if (verbose) printf("Made thread %d\n", tid2);

  for (j = 1; j <= 10000000; j++)
    {
      if (verbose) printf("top %d\n", pthread_self ());
      common_routine (0);
      sleep(1);
      t += j;
    }
  
  exit(0);
}


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

* Re: Daniel, thread vs. fork question.
  2004-03-11  1:08 Daniel, thread vs. fork question Michael Snyder
@ 2004-03-19  0:09 ` Daniel Jacobowitz
  2004-03-11  1:51   ` Daniel Jacobowitz
  2004-03-19  0:09   ` Michael Snyder
  2004-03-19  0:09 ` Michael Snyder
  2004-03-22 17:12 ` Daniel Jacobowitz
  2 siblings, 2 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19  0:09 UTC (permalink / raw)
  To: Michael Snyder; +Cc: gdb-patches

On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
> Hey Daniel,
> 
> Got a question concerning the code in 
> linux-nat.c::linux_handle_extended_wait.
> 
> You've got a PTRACE_EVENT_FORK event, and now you're going to call 
> waitpid.  You pull a pid out of a list of stopped pids, and wait for
> it using waitpid.  In your comment, you explain that you don't have to
> worry about the pid being a clone, because you didn't ask for pids in
> the event mask.
> 
> But how is this affected by threads, especially NPTL threads?
> I've got a fairly simple test-case (modified from pthreads.c,
> I'll attach it), in which a child thread calls fork -- but gdb
> apparently tries to wait on the main thread (or perhaps the most
> recent event thread).  Since that's not the thread that called
> fork, waitpid returns -1 with "no child".  Gdb reports:
> 	waiting for new child: No child processes.
> 
> FWIW, I've tried this on both a single-processor and an SMP machine.

No attachment?  Also, what glibc/nptl version are you using.

It's entirely possible that I didn't handle some threaded case.  But we
save the PID that we plan to wait on, which should be the child thread,
so I don't see how what you're describing can happn.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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

* Daniel, thread vs. fork question.
  2004-03-11  1:08 Daniel, thread vs. fork question Michael Snyder
  2004-03-19  0:09 ` Daniel Jacobowitz
@ 2004-03-19  0:09 ` Michael Snyder
  2004-03-22 17:12 ` Daniel Jacobowitz
  2 siblings, 0 replies; 11+ messages in thread
From: Michael Snyder @ 2004-03-19  0:09 UTC (permalink / raw)
  To: Daniel Jacobowitz, gdb-patches

Hey Daniel,

Got a question concerning the code in 
linux-nat.c::linux_handle_extended_wait.

You've got a PTRACE_EVENT_FORK event, and now you're going to call 
waitpid.  You pull a pid out of a list of stopped pids, and wait for
it using waitpid.  In your comment, you explain that you don't have to
worry about the pid being a clone, because you didn't ask for pids in
the event mask.

But how is this affected by threads, especially NPTL threads?
I've got a fairly simple test-case (modified from pthreads.c,
I'll attach it), in which a child thread calls fork -- but gdb
apparently tries to wait on the main thread (or perhaps the most
recent event thread).  Since that's not the thread that called
fork, waitpid returns -1 with "no child".  Gdb reports:
	waiting for new child: No child processes.

FWIW, I've tried this on both a single-processor and an SMP machine.

Michael




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

* Re: Daniel, thread vs. fork question.
  2004-03-19  0:09   ` Michael Snyder
  2004-03-11  2:22     ` Michael Snyder
@ 2004-03-19 19:29     ` Michael Snyder
  2004-03-19 19:39       ` Daniel Jacobowitz
  1 sibling, 1 reply; 11+ messages in thread
From: Michael Snyder @ 2004-03-19 19:29 UTC (permalink / raw)
  To: Michael Snyder; +Cc: Daniel Jacobowitz, gdb-patches

Michael Snyder wrote:
> Daniel Jacobowitz wrote:
> 
>> On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
>>
>>> Hey Daniel,
>>>
>>> Got a question concerning the code in 
>>> linux-nat.c::linux_handle_extended_wait.
>>>
>>> You've got a PTRACE_EVENT_FORK event, and now you're going to call 
>>> waitpid.  You pull a pid out of a list of stopped pids, and wait for
>>> it using waitpid.  In your comment, you explain that you don't have to
>>> worry about the pid being a clone, because you didn't ask for pids in
>>> the event mask.
>>>
>>> But how is this affected by threads, especially NPTL threads?
>>> I've got a fairly simple test-case (modified from pthreads.c,
>>> I'll attach it), in which a child thread calls fork -- but gdb
>>> apparently tries to wait on the main thread (or perhaps the most
>>> recent event thread).  Since that's not the thread that called
>>> fork, waitpid returns -1 with "no child".  Gdb reports:
>>>     waiting for new child: No child processes.
>>>
>>> FWIW, I've tried this on both a single-processor and an SMP machine.
>>
>>
>>
>> No attachment? 
> 
> 
> Argh.  Inevitable, isn't it?  See currently attached.
> 
>  > Also, what glibc/nptl version are you using.
> 
> Well, it's RHEL3, so I believe it's glibc 2.3 and nptl
> (not sure what version of nptl).
> 
>> It's entirely possible that I didn't handle some threaded case.  But we
>> save the PID that we plan to wait on, which should be the child thread,
>> so I don't see how what you're describing can happn.
> 
> 
> It's repeatable, on at least 3 machines.  Let me know (now that I've
> actually provided the test case) if you can't reproduce it.

Hey Daniel, have you had a chance to try and reproduce this?
I've now had a second (completely unrelated) person call it to
my attention.  New information -- I've got two fenceposts for you.

Apparently this did not happen as of 11/29/2002, but did happen
as of 1/6/2004.  These dates are from the internal Red Hat
repository, though, so they probably lag the dates in sourceware
somewhat.


> 
> 
> ------------------------------------------------------------------------
> 
> /* Pthreads test program.
>    Copyright 1996, 2002, 2003
>    Free Software Foundation, Inc.
> 
>    Written by Fred Fish of Cygnus Support
>    Contributed by Cygnus Support
> 
>    This file is part of GDB.
> 
>    This program is free software; you can redistribute it and/or modify
>    it under the terms of the GNU General Public License as published by
>    the Free Software Foundation; either version 2 of the License, or
>    (at your option) any later version.
>    
>    This program is distributed in the hope that it will be useful,
>    but WITHOUT ANY WARRANTY; without even the implied warranty of
>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>    GNU General Public License for more details.
>    
>    You should have received a copy of the GNU General Public License
>    along with this program; if not, write to the Free Software
>    Foundation, Inc., 59 Temple Place - Suite 330,
>    Boston, MA 02111-1307, USA.  */
> 
> #include <stdio.h>
> #include <pthread.h>
> 
> /* Under OSF 2.0 & 3.0 and HPUX 10, the second arg of pthread_create
>    is prototyped to be just a "pthread_attr_t", while under Solaris it
>    is a "pthread_attr_t *".  Arg! */
> 
> #if defined (__osf__) || defined (__hpux__)
> #define PTHREAD_CREATE_ARG2(arg) arg
> #define PTHREAD_CREATE_NULL_ARG2 null_attr
> static pthread_attr_t null_attr;
> #else
> #define PTHREAD_CREATE_ARG2(arg) &arg
> #define PTHREAD_CREATE_NULL_ARG2 NULL
> #endif
> 
> static int verbose = 0;
> 
> static void
> common_routine (arg)
>      int arg;
> {
>   static int from_thread1;
>   static int from_thread2;
>   static int from_main;
>   static int hits;
>   static int full_coverage;
> 
>   if (verbose) printf("common_routine (%d)\n", arg);
>   hits++;
>   switch (arg)
>     {
>     case 0:
>       from_main++;
>       break;
>     case 1:
>       from_thread1++;
>       break;
>     case 2:
>       from_thread2++;
>       break;
>     }
>   if (from_main && from_thread1 && from_thread2)
>     full_coverage = 1;
> }
> 
> static void *
> thread1 (void *arg)
> {
>   int i;
>   int z = 0;
> 
>   if (verbose) printf ("thread1 (%0x) ; pid = %d\n", arg, getpid ());
>   for (i=1; i <= 10000000; i++)
>     {
>       if (verbose) printf("thread1 %d\n", pthread_self ());
>       z += i;
>       common_routine (1);
>       sleep(1);
>     }
>   return (void *) 0;
> }
> 
> static void *
> thread2 (void * arg)
> {
>   int i;
>   int k = 0;
> 
>   if (verbose) printf ("thread2 (%0x) ; pid = %d\n", arg, getpid ());
>   for (i=1; i <= 10000000; i++)
>     {
>       if (verbose) printf("thread2 %d\n", pthread_self ());
>       k += i;
>       common_routine (2);
>       sleep(1);
>     }
>   sleep(100);
>   return (void *) 0;
> }
> 
> static void *
> forkthread (void *arg)
> {
>   int pid = fork ();
>   int ret = 0, status = 0;
> 
>   switch (pid) {
>   case 0:	/* child */
>     printf ("I'm the child, my pid = %d\n", getpid ());
>     break;
>   case -1:	/* Parent, failed to create child */
>   default:	/* Parent, fork succeeded.  */
>     printf ("I'm the parent, mypid = %d, fork returned %d\n",
> 	    getpid (), pid);
>     if (pid == -1)
>       perror ("fork failed: ");
>     else
>       waitpid (pid, &status, 0);
>   }
> }
> 
> void
> foo (a, b, c)
>      int a, b, c;
> {
>   int d, e, f;
> 
>   if (verbose) printf("a=%d\n", a);
> }
> 
> main(argc, argv)
>      int argc;
>      char **argv;
> {
>   pthread_t tid1, tid2, forktid;
>   int j;
>   int t = 0;
>   void (*xxx) ();
>   pthread_attr_t attr;
> 
>   if (verbose) printf ("pid = %d\n", getpid());
> 
>   foo (1, 2, 3);
> 
> #ifndef __osf__
>   if (pthread_attr_init (&attr))
>     {
>       perror ("pthread_attr_init 1");
>       exit (1);
>     }
> #endif
> 
> #ifdef PTHREAD_SCOPE_SYSTEM
>   if (pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM))
>     {
>       perror ("pthread_attr_setscope 1");
>       exit (1);
>     }
> #endif
> 
>   if (pthread_create (&tid1, PTHREAD_CREATE_ARG2(attr), thread1, (void *) 0xfeedface))
>     {
>       perror ("pthread_create 1");
>       exit (1);
>     }
>   if (verbose) printf ("Made thread %d\n", tid1);
>   sleep (1);
> 
>   if (pthread_create (&tid2, PTHREAD_CREATE_NULL_ARG2, thread2, (void *) 0xdeadbeef))
>     {
>       perror ("pthread_create 2");
>       exit (1);
>     }
>   if (verbose) printf("Made thread %d\n", tid2);
>   sleep (1);
> 
>   if (pthread_create (&forktid, PTHREAD_CREATE_NULL_ARG2, forkthread, (void *) 0xdeadbeef))
>     {
>       perror ("pthread_create 3 (fork)");
>       exit (1);
>     }
>   if (verbose) printf("Made thread %d\n", tid2);
> 
>   for (j = 1; j <= 10000000; j++)
>     {
>       if (verbose) printf("top %d\n", pthread_self ());
>       common_routine (0);
>       sleep(1);
>       t += j;
>     }
>   
>   exit(0);
> }
> 



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

* Re: Daniel, thread vs. fork question.
  2004-03-19 19:29     ` Michael Snyder
@ 2004-03-19 19:39       ` Daniel Jacobowitz
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19 19:39 UTC (permalink / raw)
  To: Michael Snyder; +Cc: gdb-patches

On Fri, Mar 19, 2004 at 07:29:47PM +0000, Michael Snyder wrote:
> Hey Daniel, have you had a chance to try and reproduce this?
> I've now had a second (completely unrelated) person call it to
> my attention.  New information -- I've got two fenceposts for you.
> 
> Apparently this did not happen as of 11/29/2002, but did happen
> as of 1/6/2004.  These dates are from the internal Red Hat
> repository, though, so they probably lag the dates in sourceware
> somewhat.

Sorry, I haven't - but I did see something similar from another source
internally this week.  Go figure.

I'm traveling right now - will try to look at this Monday or Tuesday.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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

* Re: Daniel, thread vs. fork question.
  2004-03-11  1:08 Daniel, thread vs. fork question Michael Snyder
  2004-03-19  0:09 ` Daniel Jacobowitz
  2004-03-19  0:09 ` Michael Snyder
@ 2004-03-22 17:12 ` Daniel Jacobowitz
  2004-03-22 20:20   ` [patch] Fix threads vs. fork following Daniel Jacobowitz
  2 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2004-03-22 17:12 UTC (permalink / raw)
  To: Michael Snyder; +Cc: gdb-patches

On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
> Hey Daniel,
> 
> Got a question concerning the code in 
> linux-nat.c::linux_handle_extended_wait.
> 
> You've got a PTRACE_EVENT_FORK event, and now you're going to call 
> waitpid.  You pull a pid out of a list of stopped pids, and wait for
> it using waitpid.  In your comment, you explain that you don't have to
> worry about the pid being a clone, because you didn't ask for pids in
> the event mask.
> 
> But how is this affected by threads, especially NPTL threads?
> I've got a fairly simple test-case (modified from pthreads.c,
> I'll attach it), in which a child thread calls fork -- but gdb
> apparently tries to wait on the main thread (or perhaps the most
> recent event thread).  Since that's not the thread that called
> fork, waitpid returns -1 with "no child".  Gdb reports:
> 	waiting for new child: No child processes.
> 
> FWIW, I've tried this on both a single-processor and an SMP machine.

Actually, what happens is GDB tries to wait on pid 0.  Here's why:

      errno = 0;
      ret = ptrace (PTRACE_GETEVENTMSG, pid, 0, &new_pid);
      printf ("getevent: ret %d, errno %d, new_pid %d\n", ret, errno, new_pid);

getevent: ret 0, errno 0, new_pid 0
waiting for new child: No child processes.

So PTRACE_GETEVENTMSG did not return the correct message.  I can't see
why it doesn't.  My guess is that I overlooked something big in the
kernel-side implementation but I'm going to have to go digging to
figure out what it is.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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

* [patch] Fix threads vs. fork following
  2004-03-22 17:12 ` Daniel Jacobowitz
@ 2004-03-22 20:20   ` Daniel Jacobowitz
  2004-03-23 20:17     ` Michael Snyder
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2004-03-22 20:20 UTC (permalink / raw)
  To: Michael Snyder, gdb-patches

On Mon, Mar 22, 2004 at 12:12:18PM -0500, Daniel Jacobowitz wrote:
> On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
> > Hey Daniel,
> > 
> > Got a question concerning the code in 
> > linux-nat.c::linux_handle_extended_wait.
> > 
> > You've got a PTRACE_EVENT_FORK event, and now you're going to call 
> > waitpid.  You pull a pid out of a list of stopped pids, and wait for
> > it using waitpid.  In your comment, you explain that you don't have to
> > worry about the pid being a clone, because you didn't ask for pids in
> > the event mask.
> > 
> > But how is this affected by threads, especially NPTL threads?
> > I've got a fairly simple test-case (modified from pthreads.c,
> > I'll attach it), in which a child thread calls fork -- but gdb
> > apparently tries to wait on the main thread (or perhaps the most
> > recent event thread).  Since that's not the thread that called
> > fork, waitpid returns -1 with "no child".  Gdb reports:
> > 	waiting for new child: No child processes.
> > 
> > FWIW, I've tried this on both a single-processor and an SMP machine.

Here's what happened: I was using ptid_get_pid, which gave me the
_process_ ID rather than the _lwp_ ID.  I've committed this fix for
HEAD.  Should I fix this on the 6.1 branch also?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2004-03-22  Daniel Jacobowitz  <drow@mvista.com>

	* lin-lwp.c (lin_lwp_wait): Pass the LWP ID to
	linux_handle_extended_wait.

Index: lin-lwp.c
===================================================================
RCS file: /cvs/src/src/gdb/lin-lwp.c,v
retrieving revision 1.52
diff -u -p -r1.52 lin-lwp.c
--- lin-lwp.c	8 Oct 2003 20:05:56 -0000	1.52
+++ lin-lwp.c	22 Mar 2004 20:02:30 -0000
@@ -1591,8 +1591,7 @@ retry:
   /* Handle GNU/Linux's extended waitstatus for trace events.  */
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
     {
-      linux_handle_extended_wait (ptid_get_pid (trap_ptid),
-				  status, ourstatus);
+      linux_handle_extended_wait (GET_LWP (lp->ptid), status, ourstatus);
       return trap_ptid;
     }
 


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

* Re: [patch] Fix threads vs. fork following
  2004-03-22 20:20   ` [patch] Fix threads vs. fork following Daniel Jacobowitz
@ 2004-03-23 20:17     ` Michael Snyder
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Snyder @ 2004-03-23 20:17 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

Daniel Jacobowitz wrote:
> On Mon, Mar 22, 2004 at 12:12:18PM -0500, Daniel Jacobowitz wrote:
> 
>>On Thu, Mar 11, 2004 at 01:08:40AM +0000, Michael Snyder wrote:
>>
>>>Hey Daniel,
>>>
>>>Got a question concerning the code in 
>>>linux-nat.c::linux_handle_extended_wait.
>>>
>>>You've got a PTRACE_EVENT_FORK event, and now you're going to call 
>>>waitpid.  You pull a pid out of a list of stopped pids, and wait for
>>>it using waitpid.  In your comment, you explain that you don't have to
>>>worry about the pid being a clone, because you didn't ask for pids in
>>>the event mask.
>>>
>>>But how is this affected by threads, especially NPTL threads?
>>>I've got a fairly simple test-case (modified from pthreads.c,
>>>I'll attach it), in which a child thread calls fork -- but gdb
>>>apparently tries to wait on the main thread (or perhaps the most
>>>recent event thread).  Since that's not the thread that called
>>>fork, waitpid returns -1 with "no child".  Gdb reports:
>>>	waiting for new child: No child processes.
>>>
>>>FWIW, I've tried this on both a single-processor and an SMP machine.
> 
> 
> Here's what happened: I was using ptid_get_pid, which gave me the
> _process_ ID rather than the _lwp_ ID.  I've committed this fix for
> HEAD.  Should I fix this on the 6.1 branch also?
> 

I don't see why not.

FYI, I've had feedback from one user who says this patch helped get
him past the point at which he was stuck before -- but he's seeing
a new problem which may or may not be related.  He has one thread
which calls system("/bin/ls"), and system ("cd <...>").  He can now
get past at least the first few such calls under GDB, but eventually
(and non-deterministically), he sees something like:

     Detaching after fork from child process 22087.
     ---Type <return> to continue, or q <return> to quit---

And then for some unknown percent of the times when the
above occurs, it goes more like this:

     Detaching after fork from child process 21502.

     Suspended (tty output)
     [msnyder@reddwarf gdb]$ fg
     /export/msnyder/03r1-2/bin/gdb  ...
     ---Type <return> to continue, or q <return> to quit---
     Detaching after fork from child process 21510.

Any thoughts?



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

end of thread, other threads:[~2004-03-23 20:17 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-11  1:08 Daniel, thread vs. fork question Michael Snyder
2004-03-19  0:09 ` Daniel Jacobowitz
2004-03-11  1:51   ` Daniel Jacobowitz
2004-03-19  0:09   ` Michael Snyder
2004-03-11  2:22     ` Michael Snyder
2004-03-19 19:29     ` Michael Snyder
2004-03-19 19:39       ` Daniel Jacobowitz
2004-03-19  0:09 ` Michael Snyder
2004-03-22 17:12 ` Daniel Jacobowitz
2004-03-22 20:20   ` [patch] Fix threads vs. fork following Daniel Jacobowitz
2004-03-23 20:17     ` Michael Snyder

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