在SIGTRAP上是否有任何与arch不可知的方式获取指令指针?

问题描述:

ptrace示踪器的角度来看,我正在寻找一种与arch不可知的方式来获取SIGTRAP生成的最后一次尝试指令(或一个过去的指令)的指令指针(AKA程序计数器)。在SIGTRAP上是否有任何与arch不可知的方式获取指令指针?

依赖拱形的方法是使用PTRACE_GETREGS并选择例如EIP在i386上,RIP在x86_64,PC在ARM等。

我使用siginfo.si_addr以及siginfo.si_ptrPTRACE_GETSIGINFO -returned结构试过,但这些值出现完全错误的(4个十六进制数字,而不是8,而不是甚至与真实地址相似),所以它们似乎不是我所需要的。

在Linux中我也尝试利用的/proc/<pid>/task/<tid>/stat 30场,其中内核fs/proc/array.c:do_task_stat()填满了KSTK_EIP(task)(其中,尽管被命名x86的中心,出现了许多其他架构的定义)。但由于某种原因,在我的ARMv6 Linux 4.9.28+(Raspbian 8)上,我得到了程序计数器和堆栈指针的零。

那么,是否有任何独立于arch的方式来确定由POSIX定义的当前/下一个地址,或者至少在Linux中可用?

+0

你如何设置你的信号处理? [你正在使用'sigaction()'并在'sa_flags'结构成员中设置'SA_SIGINFO'标志吗?](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html)如果是这样,你可能发现了一个错误。 POSIX命令'si_addr'成员引用错误指令。请参阅http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html#tag_13_43您应该添加更多信息,包括您的代码以及系统详细信息,例如硬件和确切的操作系统。 –

+1

@AndrewHenle我开始了一个新进程,它使用'PTRACE_TRACEME'调用'ptrace',然后使用'waidpid'等待父进程中的第一个调试事件。这个事件是'SIGTRAP'。你的链接只是说'SIGILL'和'SIGFPE'' si_addr'是错误指令的地址,但没有说SIGTRAP的任何内容。 – Ruslan

您可以使用/proc/[pid]/syscall

[email protected]:~$ 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) 

[email protected]:~/$ 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 

(请参阅77860被跟踪 - t

[email protected]:~/$ sudo cat /proc/77860/syscall 
23 0x1 0x7fffffffd980 0x0 0x0 0x0 0x7ffff7fdb700 0x7fffffffd958 0x7ffff78ed573 

0x7fffffffd958sp0x7ffff78ed573是程序计数器。

我找不到任何ptrace呼叫在这里帮助。

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". 
+1

的确,我已经检查过了,至少在x86,x68_64和ARM上看起来似乎起作用。 – Ruslan