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