https://bugs.kde.org/show_bug.cgi?id=364779
--- Comment #7 from Thiago Macieira <thi...@kde.org> --- Ok, I could reproduce this locally and I've got an strace: This is forkfd creating the child process: 115218 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd10015bc10) = 115247 115247 set_robust_list(0x7fd10015bc20, 24 <unfinished ...> 115218 write(28, "*\0\0\0\0\0\0\0", 8 <unfinished ...> 115247 <... set_robust_list resumed> ) = 0 115218 <... write resumed> ) = 8 115218 close(28) = 0 115247 read(28, "*\0\0\0\0\0\0\0", 8) = 8 The sequence of reads and writes synchronise parent and child, so we're sure that the entries in the forkfd global is fine. The child process exits and the parent reads the error message from chdir: 115247 exit_group(-1) = ? 115218 write(6, "\1\0\0\0\0\0\0\0", 8) = 8 115218 pselect6(25, [24], NULL, NULL, {30, 0}, {NULL, 8}) = 1 (in [24], left {29, 999993180}) 115218 write(6, "\1\0\0\0\0\0\0\0", 8) = 8 115218 read(24, "N\0o\0 \0s\0u\0c\0h\0 \0f\0i\0l\0e\0 \0o\0r\0 \0"..., 1024) = 50 115218 write(6, "\1\0\0\0\0\0\0\0", 8) = 8 115218 close(24) = 0 Note how you can tell which version of Qt this is from the strace :-) The code above is in QProcess (QProcessPrivate::_q_startupNotification and QProcessPrivate::processStarted). As a result, the QProcess change state to QProcess::NotRunning and emits error() with QProcess::FailedToStart. Immediately after this, something weird happens: 115218 rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER|SA_RESTART, 0x7fd0ffa019f0}, {0x7fd0fbfac190, [], SA_RESTORER|SA_NOCLDSTOP, 0x7fd0ffa019f0}, 8) = 0 115218 clone( <unfinished ...> 115247 +++ exited with 255 +++ 115218 <... clone resumed> child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd10015bc10) = ? ERESTARTNOINTR (To be restarted) 115218 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=115247, si_uid=1000, si_status=255, si_utime=0, si_stime=0} --- 115218 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd10015bc10) = 115249 115249 set_robust_list(0x7fd10015bc20, 24) = 0 115218 wait4(115249, <unfinished ...> 115249 dup2(13, 0) = 0 115249 dup2(13, 1) = 1 115249 execve("/usr/lib/utempter/utempter", ["/usr/lib/utempter/utempter", "del"], [/* 119 vars */]) = 0 The parent process replaces the SIGCHLD handler: I can tell it's not forkfd because it's missing the SA_NOCLDSTOP flag. Immediately thereafter, the child process that failed to chdir() exits and its SIGCHLD is notified. But forkfd's signal handler was never called, so it never writes to the pipe. The bug is not in forkfd. It's in konsole for replacing the signal handler at the most inopportune moment. sigaction() is NOT async-signal-safe. DO NOT call it if there's a chance that the signal you're looking for will be delivered at that exact time. After all of this happens, utempter exits and the signal handler is restored: 115249 exit_group(1) = ? 115249 +++ exited with 1 +++ 115218 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 115249 115218 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=115249, si_uid=1000, si_status=1, si_utime=0, si_stime=0} --- 115218 rt_sigaction(SIGCHLD, {0x7fd0fbfac190, [], SA_RESTORER|SA_NOCLDSTOP, 0x7fd0ffa019f0}, NULL, 8) = 0 115218 read(26, <unfinished ...> Note the presence of SA_NOCLDSTOP. That read() never returns, so it's the same as the backtrace, stuck inside QProcessPrivate::waitForDeadChild. Conclusion: starting utempter was done as a response to QProcess changing state or emitting the error() signal. It's not a thread issue, it's just Konsole doing the one thing that it shouldn't have done in response to a failure to start: replace the SIGCHLD handler. -- You are receiving this mail because: You are watching all bug changes.