[konsole] [Bug 364779] konsole becomes unresponsive when creating a new tab with removed directory
Thiago Macieira via KDE Bugzilla
bugzilla_noreply at kde.org
Sat Aug 13 17:52:36 UTC 2016
https://bugs.kde.org/show_bug.cgi?id=364779
--- Comment #7 from Thiago Macieira <thiago at 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 the assignee for the bug.
More information about the konsole-devel
mailing list