Bug 230856 - tail -f fails unexpectedly with EINTR if truss is run against it.
Summary: tail -f fails unexpectedly with EINTR if truss is run against it.
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-24 02:37 UTC by jeff.lawson
Modified: 2018-08-31 21:19 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jeff.lawson 2018-08-24 02:37:05 UTC
obj@tibte:~$ freebsd-version
11.1-RELEASE-p10
obj@tibte:~$ uname -a
FreeBSD tibte.hou.flightaware.com 11.1-RELEASE-p10 FreeBSD 11.1-RELEASE-p10 #0: Tue May  8 05:21:56 UTC 2018     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64

To reproduce, in one shell:

obj@tibte:~$ touch dummyfile
obj@tibte:~$ tail -f dummyfile 

In a second shell: 

obj@tibte:~$ truss -p 46364    # PID of 'tail -f' process
write(2,"tail: ",6) = 6 (0x6)
write(2,"kevent",6) = 6 (0x6)
write(2,": ",2) = 2 (0x2)
stat("/usr/share/nls/C/libc.cat",0x7fffffffe2e8) ERR#2 'No such file or directory'
stat("/usr/share/nls/libc/C",0x7fffffffe2e8)  ERR#2 'No such file or directory'
stat("/usr/local/share/nls/C/libc.cat",0x7fffffffe2e8) ERR#2 'No such file or directory'
stat("/usr/local/share/nls/libc/C",0x7fffffffe2e8) ERR#2 'No such file or directory'
write(2,"Interrupted system call\n",24)  = 24 (0x18)
sigprocmask(SIG_BLOCK,{ SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2 },{ }) = 0 (0x0)
sigprocmask(SIG_SETMASK,{ },0x0) = 0 (0x0)
sigprocmask(SIG_BLOCK,{ SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2 },{ }) = 0 (0x0)
sigprocmask(SIG_SETMASK,{ },0x0) = 0 (0x0)
sigprocmask(SIG_BLOCK,{ SIGHUP|SIGINT|SIGQUIT|SIGKILL|SIGPIPE|SIGALRM|SIGTERM|SIGURG|SIGSTOP|SIGTSTP|SIGCONT|SIGCHLD|SIGTTIN|SIGTTOU|SIGIO|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGINFO|SIGUSR1|SIGUSR2 },{ }) = 0 (0x0)
sigprocmask(SIG_SETMASK,{ },0x0) = 0 (0x0)
exit(0x1) 
process exit, rval = 1

First shell, tail has died:

tail: kevent: Interrupted system call
Comment 1 Conrad Meyer freebsd_committer 2018-08-25 02:29:24 UTC
Also occurs on CURRENT.  Certainly due to SIGSTOP raised by ptrace PT_ATTACH.  I'm not sure if restartable syscalls should EINTR on SIGSTOP by default or not.
Comment 2 Conrad Meyer freebsd_committer 2018-08-25 02:30:45 UTC
FWIW, I don't believe this is specific to tail -- any process in kevent() that doesn't mask SIGSTOP probably trips in the same way.
Comment 3 John Baldwin freebsd_committer freebsd_triage 2018-08-27 16:11:38 UTC
This is a known longstanding issue with ptrace() and not trivially fixable.  (It's also documented in truss's manpage I think, or perhaps only in gcore's manpage.)  I have been trying to work on a possible solution for several months, but it won't be ready any time soon.  (In particular, the issue is that ptrace() doesn't pass the signal to the debugger which then discards it until after it has awakened the sleeping thread and forced it out to the user/kernel boundary.  The fix I'm working on aims to keep the thread asleep while letting the debugger intercept the signal and only interrupting the thread if the debugger passes the signal.  The current WIP can be found here, but it's not really tested at all yet and I think it still panics when trying to use ptrace(): https://github.com/freebsd/freebsd/compare/master...bsdjhb:spurious_EINTR )