Re: [bmake] bmake sigint handling causing tty corruption

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Thu, 20 Jul 2017 14:29:04 +0300
On Tue, Jul 18, 2017 at 11:57:00PM +0300, Dmitry Marakasov wrote:
> Hi!
> 
> Me and Ilya Arkhipov were investigating the cause of this bug:
> 
> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=215572
> 
> In short, when FreeBSD ports options dialog is interrupted by Ctrl+C,
> there's chance of sporadic terminal corruption. They are not always
> reproducible and seem to be dependent on a machine, shell, terminal,
> tmux used, but are not tied to any specific configuration.
> 
> The investigation led us to the following conclusion:
> 
> - the corruption is caused by dialog4ports program (which handles ports
>   options dialogs) not being able to restore terminal state on exit
> - dialog4ports does indeed try to restore terminal state, but the
>   corresponding ioctl (TIOCSETAW) fails with EIO
> - examining kern/tty.c suggests that this happens likely because the make
>   which is the session leader or something dies before dialog4ports
> - which led us to bmake as a culprit
> 
> Here's the ktrace of the problem (the process hierarchy here is make ->
> sh -> dialog4ports)
> 
> ---
> 78337 dialog4ports CALL  sigaction(SIGTSTP,0x800a80228,0)
> 78337 dialog4ports RET   sigaction 0
> 78337 dialog4ports CALL  clock_gettime(0xd,0x7fffffffde08)
> 78337 dialog4ports RET   clock_gettime 0
> 78337 dialog4ports CALL  gettimeofday(0x7fffffffdc90,0)
> 78337 dialog4ports RET   gettimeofday 0
> 78337 dialog4ports CALL  poll(0x7fffffffdca0,0x2,0xffffffff)
> 
> (make and sh receive SIGINT first)
> 
> 78265 make     RET   wait4 RESTART
> 78335 sh       RET   wait4 -1 errno 4 Interrupted system call
> 78265 make     PSIG  SIGINT caught handler=0x402530 mask=0x0 code=SI_KERNEL
> 78335 sh       PSIG  SIGINT caught handler=0x41b950 mask=0x0 code=SI_KERNEL
> 78265 make     CALL  lstat(0x800ab9900,0x7fffffffd1f0)
> 78265 make     NAMI  "do-config"
> 78335 sh       CALL  sigreturn(0x7fffffffd280)
> 78335 sh       RET   sigreturn JUSTRETURN
> 78265 make     RET   lstat -1 errno 2 No such file or directory
> 78335 sh       CALL  wait4(0xffffffff,0x7fffffffd6ec,0,0)
> 78265 make     CALL  sigaction(SIGINT,0x7fffffffd250,0x7fffffffd230)
> 78265 make     RET   sigaction 0
> 78265 make     CALL  kill(0x131b9,SIGINT)
> 78265 make     RET   kill 0
> 78265 make     CALL  sigreturn(0x7fffffffd2d0)
> 78265 make     RET   sigreturn JUSTRETURN
> 
> (make kills itself)
> 
> 78265 make     PSIG  SIGINT SIG_DFL code=SI_USER
> 
> (dialog4ports finally starts to process the signal)
> 
> 78337 dialog4ports RET   poll -1 errno 4 Interrupted system call
> 78337 dialog4ports PSIG  SIGINT caught handler=0x800855e00 mask=0x0 code=SI_KERNEL
> 78337 dialog4ports CALL  sigaction(SIGINT,0x7fffffffd7c0,0)
> 78337 dialog4ports RET   sigaction 0
> 78337 dialog4ports CALL  ioctl(0x1,TIOCGETA,0x7fffffffd770)
> 78337 dialog4ports RET   ioctl 0
> 78337 dialog4ports CALL  write(0x1,0x801676a00,0x17)
> 78337 dialog4ports GIO   fd 1 wrote 23 bytes
> 78337 dialog4ports RET   write 23/0x17
> 
> (this call should restore terminal state, but it fails)
> 
> 78337 dialog4ports CALL  ioctl(0x1,TIOCSETAW,0x80161604c)
> 78337 dialog4ports RET   ioctl -1 errno 5 Input/output error
> 78337 dialog4ports CALL  exit(0x1)

It is indeed likely that this is due to terminal access from the orphaned
process group.  To make it completely sure diagnostic, you need to look
at the terminal state and at the process state, including the process group,
process session and the orphaned state.

I just find is somewhat strange that make initiates a new session.
Shell should not create a new session, since passed arguments (a command
to execute) should make it non-interactive.

Did you verified that enabling the wait code in make(1) fixes the issue ?
Received on Thu Jul 20 2017 - 09:29:12 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:12 UTC