I'm attaching to a process with ptrace(PTRACE_ATTACH...) while it is in a syscall (like nanosleep()). I can use PTRACE_GETREGS to get the register contents, and eip is at expected location (in __kernel_vsyscall). However, eax and orig_eax registers have unexpected contents: eax usually contains -516, and orig_eax is usually 0.
This is the test program I used (taken from http://www.linuxjournal.com/article/6210 and slightly modified):
#include <stdlib.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
int main(int argc, char *argv[])
{
pid_t traced_process;
struct user_regs_struct regs;
long ins;
if(argc != 2) {
printf("Usage: %s <pid to be traced>\n",
argv[0]);
exit(1);
}
traced_process = atoi(argv[1]);
ptrace(PTRACE_ATTACH, traced_process,
NULL, NULL);
wait(NULL);
ptrace(PTRACE_GETREGS, traced_process,
NULL, ®s);
printf("eax: %lx (%d); orig_eax: %lx\n",
regs.eax, (int)regs.eax, regs.orig_eax);
ins = ptrace(PTRACE_PEEKTEXT, traced_process,
regs.eip, NULL);
printf("EIP: %lx Instruction executed: %lx\n",
regs.eip, ins);
ptrace(PTRACE_DETACH, traced_process,
NULL, NULL);
return 0;
}
Output when attaching to a "sleep 10000" command running in another terminal:
eax: fffffdfc (-516); orig_eax: 0
EIP: b7711424 Instruction executed: c3595a5d
What does the value in eax mean? Why doesn't orig_eax contain the original syscall number (like 162)? And how do I actually get the system call number in this case?
Also, why does gdb correctly shows "162" for "print $orig_eax"?
Btw. this is on Ubuntu 12.04, with kernel 3.2.0:
which sleep
: "/bin/sleep: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x0965431bde4d183eaa2fa3e3989098ce46b92129, stripped".So it's a 32-bit PAE kernel and 32-bit Ubuntu installation on 64-bit CPU.
This is on Ubuntu 12.04, with kernel 3.2.0
This doesn't uniquely identify your system. What processor?
My crystal ball tells me that sleep
you are invoking is a 64-bit program, while your tracer program is not. Or vice versa.