I'm looking for an arch-agnostic way to obtain the instruction pointer (AKA program counter) of the last attempted instruction (or one past it) on which SIGTRAP was generated, from the perspective of a ptrace
tracer.
An arch-dependent way is to use PTRACE_GETREGS
and pick e.g. EIP
on i386, RIP
on x86_64, PC
on ARM etc..
I've tried using siginfo.si_addr
as well as siginfo.si_ptr
from PTRACE_GETSIGINFO
-returned struct, but these values appear completely wrong (4 hex digits instead of 8, and not even similar to the true address), so they don't seem to be what I need.
In Linux I've also tried making use of 30th field of /proc/<pid>/task/<tid>/stat
, which the kernel fills in fs/proc/array.c:do_task_stat()
with KSTK_EIP(task)
(which, despite being named x86-centric, appears defined for many other architectures). But for some reason on my ARMv6 Linux 4.9.28+ (Raspbian 8) I get zeros for both program counter and stack pointer.
So, is there any arch-independent way of determining the current/next address defined by POSIX or at least available in Linux?
You might use /proc/[pid]/syscall
.
mark@ubuntu:~$ gdb python
...
...
...
Program received signal SIGINT, Interrupt.
0x00007ffff78ed573 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb)
mark@ubuntu:~/$ ps aux | grep python
mark 77858 0.2 0.7 90216 37780 pts/2 S+ 15:13 0:00 gdb python
mark 77860 0.0 0.1 38416 6424 pts/2 t 15:13 0:00 /usr/bin/python
(see that 77860
is traced - t
)
mark@ubuntu:~/$ sudo cat /proc/77860/syscall
23 0x1 0x7fffffffd980 0x0 0x0 0x0 0x7ffff7fdb700 0x7fffffffd958 0x7ffff78ed573
0x7fffffffd958
is sp
and 0x7ffff78ed573
is the program counter.
I couldn't find any ptrace
call that helps here.
http://man7.org/linux/man-pages/man5/proc.5.html
/proc/[pid]/syscall (since Linux 2.6.27) This file exposes the system call number and argument regis‐ ters for the system call currently being executed by the process, followed by the values of the stack pointer and pro‐ gram counter registers. The values of all six argument regis‐ ters are exposed, although most system calls use fewer regis‐ ters. If the process is blocked, but not in a system call, then the file displays -1 in place of the system call number, followed by just the values of the stack pointer and program counter. If process is not blocked, then the file contains just the string "running".