This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
Re: RFA: linux-thread.c change (fixes hang on startup)
- To: Kevin Buettner <kevinb at cygnus dot com>
- Subject: Re: RFA: linux-thread.c change (fixes hang on startup)
- From: Eric Paire <paire at ri dot silicomp dot fr>
- Date: Tue, 25 Jan 2000 09:15:07 +0100
- cc: Jim Blandy <jimb at cygnus dot com>, Michael Snyder <msnyder at cygnus dot com>, gdb-patches at sourceware dot cygnus dot com
>
> I've done some digging, and it appears that SIGCHLD is *not* blocked
> explicitly by another part of gdb. (Prior to sending my patch on
> Saturday morning, I looked around for it too, but saw nothing
> obvious.) After looking a bit harder, I discovered that the process
> signal mask with SIGCHLD blocked is being inherited from the parent.
>
> Here is what I did to make this determination:
>
> 1) Debug gdb w/ gdb. (The choice of the parent gdb is critical.)
> 2) Put a breakpoint on main
> 3) Run 'til the breakpoint on main.
> 4) Determine the pid of the child with "info target"
> 5) cat out /proc/PID/status and observe the mask indicated by
> SigBlk.
>
> When I start gdb with an older gdb (gdb-4.17.0.11 which is what installs
> by default on my RH6.0 system), I see no signals blocked. OTOH, when
> I debug gdb with a recent gdb (the one that I just built myself from
> the development sources), I see:
>
> SigBlk: 0000000000010000
>
> This indicates that SIGCHLD is blocked.
>
> This leads me to the conclusion that the parent gdb is causing SIGCHLD
> to be blocked for the inferior (child) gdb.
>
> Note that this problem could occur in other settings as well. If gdb
> is invoked by a gui which communicates with it, the signal mask could
> be in an unknown/undesirable state too.
>
> I think we should attack this problem on two fronts:
>
> 1) Early in gdb's initialization, we should set the signal mask
> to some appropriate value. (Perhaps just unblock all signals.)
>
> 2) Just after forking the child (on the child's side of the fork),
> we should again reset the signal mask so that the child does
> not inherit the mask that gdb is using.
>
> I also think it's prudent to make sure that linuxthreads_block_mask
> does not block SIGCHLD.
>
> Opinions?
>
I think I have more or less understood what's going on:
1) After having read (once more ;-) the POSIX specification on exec() (3.1.2),
I have [re]discovered that the process signal mask and pending signals
are inherited by the new process image.
2) Michael's new 'linuxthreads_wait_mask' is computed by installing the new
signal mask (blocking SIGCHLD) in '_initialize_linuxthreads()'.
3) Unfortunately, '_initialize_linuxthreads()' is part of the initialization
routines which are systematically called by 'gdb_init()', whether or
not LinuxThreads are used by the debugged process.
The result is that, when you run gdb on gdb, the top level gdb runs
'_initialize_linuxthreads()' which blocks SIGCHLD. Then, it forks
the debugged gdb, but does not reset the SIGNAL mask, so that the
SIGCHLD is also blocked in the debugged GDB, thus leading to the
behaviour you've noticed. Notice that when you run gdb on any
program, the SIGCHLD of the program is also blocked (unless it
resets its signal mask), leading to the behaviour you've noticed.
My recommendation would be to remove the signal mask modification from
'_initialize_linuxthreads()', and to move it to places where
'push_target (&linuxthreads_op)' is done (actually in
'linuxthreads_attach()' and 'linuxthreads_create_inferior()'), and
to restore original signal mask (linuxthreads_block_mask) in places
where 'unpush_target (&linuxthreads_ops)' is done (actually in
'linuxthreads_detach()' and 'linuxthreads_mourn_inferior()'),
is that the signal mask handling is cleanly managed by linuxthread
package.
This should fix your current problem. Concerning the reset of the signal mask
in early GDB's initialization and just after forking the child, I
don't think that this is necessary, since the SIGCHLD bug seems to
be a misplacement of the signal mask handling in linuxthread support.
My opinion is that if such problem arise once more, then this is
because signal handling is not correctly handled by GDB targets.
Finally, the fact that signals are not blocked with gdb-4.17.0.11 is that
my original patches on gdb-4.17 did not block SIGCHLD, but this
lead to high load in GDB due to useless SIGCHLD handling on thread
event (one SIGCHLD each time a thread was stopped or restarted).
Michael and I discussed the idea of blocking SIGCHLD to reduce
the GDB overhead on thread stopping/restarting.
Hope this helps,
-Eric
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Eric PAIRE
Web : http://www.ri.silicomp.com/~paire | Group SILICOMP - Research Institute
Email: eric.paire@ri.silicomp.com | 2, avenue de Vignate
Phone: +33 (0) 476 63 48 71 | F-38610 Gieres
Fax : +33 (0) 476 51 05 32 | FRANCE