Re: man-pages-3.37 is released
From: Michael Kerrisk (man-pages)
Date: Mon Mar 19 2012 - 14:29:47 EST
Hello Denys,
On Sat, Mar 17, 2012 at 1:16 PM, Denys Vlasenko
<vda.linux@xxxxxxxxxxxxxx> wrote:
> On Friday 09 March 2012 18:27, Michael Kerrisk (man-pages) wrote:
>> ptrace.2
>> Denys Vlasenko [Oleg Nesterov, Tejun Heo]
>> add extended description of various ptrace quirks
>
> Pulled current git and spotted a few broken places.
I made a few light edits to your patch, but basically applied it as
given for man-pages-3.38.
Thanks for checking the page over one more time!
Cheers,
Michael
> The following kinds of ptrace-stops exist: signal-delivery-stops,
> group-stop, PTRACE_EVENT stops, syscall-stops PTRACE_SINGLESTEP,
> PTRACE_SYSEMU, and They all are reported by waitpid(2) with WIF-
> STOPPED(status) true.
>
> The text is broken after "syscall-stops" word. Corresponding source is:
>
> group-stop, PTRACE_EVENT stops, syscall-stops
> .BR PTRACE_SINGLESTEP ,
> .BR PTRACE_SYSEMU ,
> and
> .BE PTRACE_SYSEMU_SINGLESTEP .
>
>
>
> Signal-delivery-stop is observed by the tracer as waitpid(2) returning
> with WIFSTOPPED(status) true, with the stopping signal returned by
> WSTOPSIG(status). If the stopping signal is SIGTRAP, this may be a
> different kind of ptrace-stop; ...
>
> The two instances of word "stopping" above are wrong and need to be deleted:
> ANY signal is reported this way, not only four signals which stop processes.
> This is an especially bad disinformation because in the sentences below
> we again use word "stopping":
>
> ... see the "Syscall-stops" and "execve"
> sections below for details. If WSTOPSIG(status) returns a stopping
> signal, this may be a group-stop; see below.
>
> but here, we do mean "stopping" = "SIGSTOP/TSTP/TTIN/TTOU".
>
>
>
> Note that a suppressed signal still causes system calls to return
> prematurely. Restartable system calls will be restarted (the tracer
> will observe the tracee to execute restart_syscall(2) if the tracer
> uses PTRACE_SYSCALL); non-restartable system calls may fail with EINTR
> even though no observable signal is injected to the tracee.
>
> I learned more about this mechanism and the above text is wrong.
> A better text would be:
>
> Note that a suppressed signal still causes system calls to return pre-
> maturely. In this case system calls will be restarted: the tracer will
> observe the tracee to re-execute interrupted system call (or
> restart_syscall(2) system call for a few syscalls which use a different
> mechanism for restarting) if the tracer uses PTRACE_SYSCALL. Even sys-
> tem calls (such as poll(2)) which are not restartable after signal are
> restarted after signal is suppressed; however, kernel bugs exist which
> cause some syscalls to fail with EINTR even though no observable signal
> is injected to the tracee.
>
>
>
> * All other threads stop in PTRACE_EVENT_EXIT stop, if the
> PTRACE_O_TRACEEXIT option was turned on. Then all other threads
> except the thread group leader report death as if they exited via
> _exit(2) with exit code 0.
>
> * Then a PTRACE_EVENT_EXEC stop happens, if the PTRACE_O_TRACEEXEC
> option was turned on.
>
> * The execing tracee changes its thread ID while it is in the
> execve(2). (Remember, under ptrace, the "pid" returned from wait-
> pid(2), or fed into ptrace calls, is the tracee's thread ID.) That
> is, the tracee's thread ID is reset to be the same as its process
> ID, which is the same as the thread group leader's thread ID.
>
> Above, bullet points 2 and 3 need to be swapped: thread ID change happens
> before PTRACE_EVENT_EXEC.
>
>
> * If the thread group leader has reported its death by this time, it
> appears to the tracer that the dead thread leader "reappears from
> nowhere".
>
> Thread group leader does not report its death until there is
> at least one other live thread.
>
>
>
> The PTRACE_O_TRACEEXEC option is the recommended tool for dealing with
> this situation. It enables PTRACE_EVENT_EXEC stop, which occurs before
> execve(2) returns. First, it enables PTRACE_EVENT_EXEC-stop, which
> occurs before execve(2) returns.
>
> Duplicate sentence.
>
> Currently, there is no way to retrieve the former thread ID of the
> execing tracee. If the tracer doesn't keep track of its tracees'
> thread group relations, it may be unable to know which tracee execed
> and therefore no longer exists under the old thread ID due to a thread
> ID change.
>
> Two paragraphs above, we just said "In this stop, the tracer can use
> PTRACE_GETEVENTMSG to retrieve the tracee's former thread ID. (This
> feature was introduced in Linux 3.0)."
> So it is no longer true.
>
>
>
> Also, I propose the following additon to BUGS:
>
> Some syscalls return with EINTR if a signal was sent to a tracee, but
> delivery was suppressed by the tracer. (This is very typical operation:
> it is usually done by debuggers on every attach, in order to not intro-
> duce a bogus SIGSTOP). As of Linux-3.2, the following syscalls are
> affected: epoll_wait(2), read(2) from inotify file descriptor. The list
> is likely incomplete.
>
>
> The patch against current git is below.
> --
> vda
>
>
>
> diff --git a/man2/ptrace.2 b/man2/ptrace.2
> index 37c4dff..7f3c219 100644
> --- a/man2/ptrace.2
> +++ b/man2/ptrace.2
> @@ -722,11 +722,7 @@ Example:
> .\" describe how wait notifications queue (or not queue)
> .LP
> The following kinds of ptrace-stops exist: signal-delivery-stops,
> -group-stop, PTRACE_EVENT stops, syscall-stops
> -.BR PTRACE_SINGLESTEP ,
> -.BR PTRACE_SYSEMU ,
> -and
> -.BE PTRACE_SYSEMU_SINGLESTEP .
> +group-stop, PTRACE_EVENT stops, syscall-stops.
> They all are reported by
> .BR waitpid (2)
> with
> @@ -766,9 +762,9 @@ Signal-delivery-stop is observed by the tracer as
> .BR waitpid (2)
> returning with
> .I WIFSTOPPED(status)
> -true, with the stopping signal returned by
> +true, with the signal returned by
> .IR WSTOPSIG(status) .
> -If the stopping signal is
> +If the signal is
> .BR SIGTRAP ,
> this may be a different kind of ptrace-stop;
> see the "Syscall-stops" and "execve" sections below for details.
> @@ -802,12 +798,17 @@ value: the tracer can cause a different signal to be injected.
> .LP
> Note that a suppressed signal still causes system calls to return
> prematurely.
> -Restartable system calls will be restarted (the tracer will
> -observe the tracee to execute
> +In this case system calls will be restarted: the tracer will
> +observe the tracee to re-execute interrupted system call (or
> .BR restart_syscall(2)
> -if the tracer uses
> -.BR PTRACE_SYSCALL );
> -non-restartable system calls may fail with
> +system call for a few syscalls which use a different mechanism
> +for restarting) if the tracer uses
> +.BR PTRACE_SYSCALL .
> +Even system calls (such as
> +.BR poll(2) )
> +which are not restartable after signal are restarted after
> +signal is suppressed; however, kernel bugs exist which cause
> +some syscalls to fail with
> .B EINTR
> even though no observable signal is injected to the tracee.
> .LP
> @@ -1406,12 +1407,6 @@ death as if they exited via
> .BR _exit (2)
> with exit code 0.
> .IP *
> -Then a
> -.B PTRACE_EVENT_EXEC
> -stop happens, if the
> -.BR PTRACE_O_TRACEEXEC
> -option was turned on.
> -.IP *
> The execing tracee changes its thread ID while it is in the
> .BR execve (2).
> (Remember, under ptrace, the "pid" returned from
> @@ -1420,9 +1415,22 @@ or fed into ptrace calls, is the tracee's thread ID.)
> That is, the tracee's thread ID is reset to be the same as its process ID,
> which is the same as the thread group leader's thread ID.
> .IP *
> -If the thread group leader has reported its death by this time,
> +Then a
> +.B PTRACE_EVENT_EXEC
> +stop happens, if the
> +.BR PTRACE_O_TRACEEXEC
> +option was turned on.
> +.IP *
> +If the thread group leader has reported its
> +.B PTRACE_EVENT_EXIT
> +stop by this time,
> it appears to the tracer that
> the dead thread leader "reappears from nowhere".
> +(Note: thread group leader does not report death via
> +.I WIFEXITED(status)
> +until there is at least one other live thread.
> +This eliminates possibility that tracer will see
> +it dying and then reappearing.)
> If the thread group leader was still alive,
> for the tracer this may look as if thread group leader
> returns from a different system call than it entered,
> @@ -1440,11 +1448,6 @@ the thread ID change in the tracee.
> The
> .B PTRACE_O_TRACEEXEC
> option is the recommended tool for dealing with this situation.
> -It enables
> -.B PTRACE_EVENT_EXEC
> -stop, which occurs before
> -.BR execve (2)
> -returns.
> First, it enables
> .BR PTRACE_EVENT_EXEC -stop,
> which occurs before
> @@ -1475,13 +1478,7 @@ data structures describing the threads of this process,
> and retain only one data structure\(emone which
> describes the single still running tracee, with
>
> - thread ID == thread group ID == process id.
> -.LP
> -Currently, there is no way to retrieve the former
> -thread ID of the execing tracee.
> -If the tracer doesn't keep track of its tracees' thread group relations,
> -it may be unable to know which tracee execed and therefore no longer
> -exists under the old thread ID due to a thread ID change.
> + thread ID == thread group ID == process ID.
> .LP
> Example: two threads call
> .BR execve (2)
> @@ -1499,10 +1496,6 @@ PID2 execve("/bin/bar", "bar" <unfinished ...>
> PID0 <... execve resumed> ) = 0
> .fi
> .LP
> -In this situation, there is no way to know which
> -.BR execve (2)
> -succeeded.
> -.LP
> If the
> .B PTRACE_O_TRACEEXEC
> option is
> @@ -1713,6 +1706,17 @@ This may be changed in the future;
> .B SIGKILL
> is meant to always immediately kill tasks even under ptrace.
> Last confirmed on 2.6.38.6.
> +.LP
> +Some syscalls return with
> +.B EINTR
> +if a signal was sent to a tracee, but delivery was suppressed
> +by the tracer. (This is very typical operation: it is usually
> +done by debuggers on every attach, in order to not introduce
> +a bogus SIGSTOP).
> +As of linux 3.2.9, the following syscalls are affected:
> +.BR epoll_wait (2),
> +.BR read (2)
> +from inotify file descriptor. The list is likely incomplete.
> .SH "SEE ALSO"
> .BR gdb (1),
> .BR strace (1),
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Author of "The Linux Programming Interface"; http://man7.org/tlpi/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/