在 Linux x86_64 系统(至少运行 2.6.32 的 RHEL 6.4)上,/proc/pid/syscall
32 位进程报告的第一个系统调用参数似乎是虚假的……我想确定原因。
例如,如果一个进程在执行 openat(AT_FDCWD, ...) 时被阻止,我会在/proc/pid/syscall
...
64 位:
257 0xffffffffffffff9c ...
32 位:
295 0xffffffff810495c0 ...
AT_FD_CWD == -100 == 0xffffffffffffff9c
,所以 64 位的情况看起来是正确的,但 32 位的值似乎已被破坏(其他参数看起来正确)。
我知道我可以在堆栈顶部找到一个 struct pt_regs,我可以通过 ...
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)
我看到那里的虚假价值。
然而...... strace 似乎能够找到第一个参数的正确值,即使在 32 位的情况下也是如此。它执行 ptrace(PTRACE_PEEKUSER),AFAIK 只是查看相同的结构 pt_regs。
我一定遗漏了一些东西...... strace 发生了什么神奇的事情,它允许它通过 PTRACE_PEEKUSER 查看有效的寄存器值?如通过 所见,破坏第一个参数会发生什么/proc/pid/syscall
?