This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: RFA: linux-thread.c change (fixes hang on startup)


On Jan 24,  3:39pm, Eric Paire wrote:

> I privately discussed the SIGCHLD management point with Michael, as this was
> one major change in the LinuxThread support behaviour I wrote code for. My
> only problem with your patch is that if SIGCHLD is blocked at that time, it
> should have been blocked intentionally by other part of GDB, and if SIGCHLD
> has not yet been unblocked, then this is a bug to fix in the right part
> of GDB, and not in the LinuxThread support, because other parts of GDB
> dealing with SIGCHLD [un]masking will also have to support the fix you
> propose.
> 
> So, I would suggest that (thanks to your program which exhibits consistently
> the problem) you try to track down the signal status in 'gdb_init()' and try
> to discover what part of GDB is incorrectly managing SIGCHLD. After having
> downloaded the latest GDB snapshot and looked at the source, I have not
> been able to see any place where the SIGCHLD is being blocked before calling
> '_initialize_linuxthreads()', but you should be able to discover that
> quickly with your test program (perhaps in the 'pre_init_ui_hook' if you use
> an UI).

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?

(If there's general agreement, I'll prepare some patches...)

Kevin

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]