трассировка процесса (process trace)
Ошибки (баги) (Bugs)
On hosts with 2.6 kernel headers, PTRACE_SETOPTIONS
is declared
with a different value than the one for 2.4. This leads to
applications compiled with 2.6 kernel headers failing when run on
2.4 kernels. This can be worked around by redefining
PTRACE_SETOPTIONS
to PTRACE_OLDSETOPTIONS
, if that is defined.
Group-stop notifications are sent to the tracer, but not to real
parent. Last confirmed on 2.6.38.6.
If a thread group leader is traced and exits by calling _exit(2),
a PTRACE_EVENT_EXIT
stop will happen for it (if requested), but
the subsequent WIFEXITED
notification will not be delivered until
all other threads exit. As explained above, if one of other
threads calls execve(2), the death of the thread group leader
will never be reported. If the execed thread is not traced by
this tracer, the tracer will never know that execve(2) happened.
One possible workaround is to PTRACE_DETACH
the thread group
leader instead of restarting it in this case. Last confirmed on
2.6.38.6.
A SIGKILL
signal may still cause a PTRACE_EVENT_EXIT
stop before
actual signal death. This may be changed in the future; SIGKILL
is meant to always immediately kill tasks even under ptrace.
Last confirmed on Linux 3.13.
Some system calls 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 introduce a bogus SIGSTOP
). As of Linux
3.2.9, the following system calls are affected (this list is
likely incomplete): epoll_wait(2), and read(2) from an inotify(7)
file descriptor. The usual symptom of this bug is that when you
attach to a quiescent process with the command
strace -p <process-ID>
then, instead of the usual and expected one-line output such as
restart_syscall(<... resuming interrupted call ...>_
or
select(6, [5], NULL, [5], NULL_
('_' denotes the cursor position), you observe more than one
line. For example:
clock_gettime(CLOCK_MONOTONIC, {15370, 690928118}) = 0
epoll_wait(4,_
What is not visible here is that the process was blocked in
epoll_wait(2) before strace(1) has attached to it. Attaching
caused epoll_wait(2) to return to user space with the error
EINTR
. In this particular case, the program reacted to EINTR
by
checking the current time, and then executing epoll_wait(2)
again. (Programs which do not expect such "stray" EINTR
errors
may behave in an unintended way upon an strace(1) attach.)
Contrary to the normal rules, the glibc wrapper for ptrace
() can
set errno to zero.