ptrace时,子进程不会继续执行

时间:2014-10-25 22:00:14

标签: c linux debugging ptrace

我做了以下简单示例,使用ptrace从子进程读取内存。

我希望在执行小型矩阵乘法程序期间每秒看到特定地址0x601050的值。我使用PTRACE_PEEKDATA后跟PTRACE_CONT并在无限循环中休眠1秒钟。

然而,矩阵乘法程序永远不会继续 - 它应该在第一条指令中打印到stdout,但它似乎永远不会执行。我知道ptrace(PTRACE_CONT,pid)会通知孩子恢复执行,而sleep(1)会允许它执行一秒钟(直到下一次ptrace调用),但事实并非如此。

#include <string.h>
#include <errno.h>
#include <inttypes.h>

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/reg.h>

int read_mem(long *out, pid_t pid, long addr, size_t sz)
{
    long tmp;
    size_t copied = 0;

    while(copied < sz)
    {
        tmp = ptrace(PTRACE_PEEKDATA, pid, addr+copied);

        if(errno)
        { 
            fprintf(stderr,"ptrace: error : %s\n",strerror(errno));
            return copied;
        }

        memcpy(out,&tmp,sizeof(long));

        copied += sizeof(long);
        out++;

        printf("ptrace: copied %d bytes\n",copied);
    }

    return copied;
}

int main()
{   
    pid_t child;
    long result;
    struct user_regs_struct regs;
    int status;

    long addr = 0x601050;
    size_t sz = sizeof(double);
    long *buf = (long*)malloc(sz);

    child = fork();

    if(child == 0) 
    {
        ptrace(PTRACE_TRACEME);
        execl("./matmul", "matmul", NULL);
    }
    else 
    {
        ptrace(PTRACE_GETREGS, child, &regs);
        printf("ptrace: regs.rip : 0x%lx\n", regs.rip);

        while(1)
        {
            read_mem(buf, child, addr, sz);
            printf("ptrace: read(0x%lx) : %f\n", addr, (double)(*buf));

            ptrace(PTRACE_CONT, child);

            sleep(1);
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

您似乎没有设置PTRACE_O_TRACEEXEC选项。如果不这样做,会导致SIGTRAP在调用exec时被发送到tracee;如果未准备,则默认操作是具有核心转储的终止。