A Wednesday 11 June 2008 18:21:05, Vladimir Prus wrote:
> Pedro, I think this SIGCHLD magic is your doing -- do
you have any ideas
> how to fix it?
Dang, I totally missed this could be a problem.
Right, so, normal_mask has SIGCHLD blocked in
_initialize_linux_nat,
and since forking a child inherits the signal mask, the
child gets
SIGCHLD blocked by default. This would have gone unnoticed
if Qt unblocked SIGCHLD in it's setup (one may argue it
should).
It's not safe to just remove that SIGCHLD blocking, we're
not
taking care of blocking it in places we used to in sync
mode
(we used to block it the first time we hit linux_nat_wait,
which
is reached after forking an inferior).
For async mode, we also need to do something about SIGCHLD
blocking. We have:
linux_nat_create_inferior
-> linux_nat_async_mask
-> linux_nat_async
-> linux_nat_async_events
-> block SIGCHLD.
-> linux_ops->to_create_inferior (forks a child)
Attached is a patch to fix this.
Basically, I turned linux_nat_async_events_enabled into a
3-state instead of a bool, with the new state being
"SIGCHLD unblocked with action set to whatever we get
on startup". Most of the SIGCHLD state management
stays with
the same logic, except that linux_nat_create_inferior gets
a
switch to the new state before forking a child, and
linux_nat_wait, gets an unconditional switch to the blocked
state. The rest of the patch is mostly updating to the
new interface.
Tested on x86-64-unknown-linux-gnu sync and async modes
without regressions.
--
Pedro Alves
|