我的strace程序在64位linux系统下输出错误

时间:2014-07-26 04:14:29

标签: linux strace ptrace

我正在建立一个在线评判系统。关键是跟踪系统调用。

我选择了ptrace。由于SIGTRAP将进入一个系统调用,子进程将停止,然后父进程将读取子进程的orig_rax(orig_eax)寄存器以获取系统调用号。

当代码在Opensuse13.1 32bit下运行时没问题,其输出与linux命令strace相同。

但我只是在Opensuse13.1 64bit,Ubuntu12.04 64bit下测试代码,输出错误。

可以在此处下载演示代码:https://gist.github.com/kainwen/41a7bd0198099d766bda

在64位Linux系统下,您保存代码strace_ls.c,将其编译为gcc strace_ls.c,然后运行./a.out 2>out。输出为here

所以我的代码输出很奇怪。

我的代码及其输出如下:

#include <sys/resource.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>

void judge_exe()
{
    pid_t pid ;
    int insyscall = 0 ;
    struct user context ;

    pid = fork() ;

    if (pid == 0) { //child
        ptrace(PTRACE_TRACEME,0,NULL,NULL) ;
        execl("/usr/bin/ls","ls",NULL) ;
    }
    else {//parent
        int status ;
        ptrace(PTRACE_SYSCALL, pid, NULL, NULL);

        while (1) {
            wait(&status) ;
            if (WIFEXITED(status))  //normally terminated
                break;
            else if (WIFSTOPPED(status) &&  (WSTOPSIG(status)==SIGTRAP)) {
                if (!insyscall) {
                    insyscall = 1;
                    ptrace(PTRACE_GETREGS,pid,NULL,&context.regs);
                    fprintf(stderr,"syscall num: %d \n",context.regs.orig_rax);
                } else
                    insyscall = 0;
            }
            ptrace(PTRACE_SYSCALL,pid,NULL,NULL);
        }
        return;
    }
}

int main(int argc, char *argv[]) {
    judge_exe();
}

上面代码的输出是(只是标题行):

syscall num: 59 
syscall num: 12 
syscall num: 9 
syscall num: 21 
syscall num: 2 
syscall num: 4 

linux命令strace ls的输出标题行是:

execve("/usr/bin/ls", ["ls"], [/* 101 vars */]) = 0
brk(0)                                  = 0x1bab000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efff4326000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib64/mpi/gcc/openmpi/lib64/tls/x86_64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/usr/lib64/mpi/gcc/openmpi/lib64/tls/x86_64", 0x7fff00c49b80) = -1 ENOENT (No such file or directory)

系统调用sys_execve的数量是11,而不是59(我的代码的输出)


解决

我的方法是对的。系统调用号在64位和32位下不同。

0 个答案:

没有答案