在Android ARM64上使用ptrace跟踪进程

在Android ARM64上使用ptrace跟踪进程,android,c,debugging,arm64,ptrace,Android,C,Debugging,Arm64,Ptrace,我在模拟AARC64的Android ARM64仿真器上使用ptrace()跟踪简单的hello world时遇到了一个无限循环。我不知道为什么它没有停止。我试图跟踪hello world程序并获取所有已执行的指令,但这种情况似乎从未返回false:while(WIFSTOPPED(wait_status)) int main(int argc,char**argv) { pid_t child_pid; 如果(argc0) 运行调试程序(子pid); 其他的 { 佩罗尔(“福克”); 返回-1

我在模拟AARC64的Android ARM64仿真器上使用ptrace()跟踪简单的hello world时遇到了一个无限循环。我不知道为什么它没有停止。我试图跟踪hello world程序并获取所有已执行的指令,但这种情况似乎从未返回false:
while(WIFSTOPPED(wait_status))

int main(int argc,char**argv)
{
pid_t child_pid;
如果(argc<2)
{
fprintf(stderr,“应将程序名作为参数\n”);
返回-1;
}
child_pid=fork();
如果(子项pid==0)
运行_目标(argv[1]);
否则如果(子项pid>0)
运行调试程序(子pid);
其他的
{
佩罗尔(“福克”);
返回-1;
}
返回0;
}
无效运行_目标(常量字符*程序名)
{
printf(“目标已启动。将运行“%s”\n”,程序名);
/*允许跟踪此进程*/
if(ptrace(ptrace_TRACEME,0,0,0)<0)
{
佩罗尔(“ptrace”);
返回;
}
/*用给定程序替换此进程的映像*/
execl(程序名,程序名,0);
}
无效运行调试程序(pid\t子pid)
{
int等待状态;
无符号icounter=0;
printf(“调试器已启动\n”);
/*等待子项在其第一条指令中停止*/
等待(&wait_状态);
while(WIFSTOPPED(等待状态))
{
icounter++;
结构用户注册;
结构iovec io;
io.iov_base=®s;
io.iov_len=sizeof(regs);
if(ptrace(ptrace_GETREGSET,child_pid,(void*)NT_PRSTATUS,(void*)和io)=-1)
printf(“错误的寄存器请求\n”);
无符号instr=ptrace(ptrace_peek text,child_pid,regs.pc,0);
printf(“icounter=%u.PCP=0x%08x.instr=0x%08x\n”,icounter,regs.pc,instr);
/*让孩子执行另一条指令*/
if(ptrace(ptrace_SINGLESTEP,child_pid,0,0)<0)
{
佩罗尔(“ptrace”);
返回;
}
/*等待孩子在下一条指令中停止*/
等待(&wait_状态);
}
printf(“子级执行了%u条指令,\n”,icounter);
}

WIFSTOPPED返回false的唯一原因是您正在跟踪的进程已退出。是吗?所以我解决了问题。在执行了很多指令之后,它确实结束了。它在androids的bastardized fork()进程中被捕获。WIFSTOPPED返回false的唯一原因是您正在跟踪的进程是否已退出。是吗?所以我解决了问题。在执行了很多指令之后,它确实结束了。它陷入了机器人的卑鄙的fork()过程。
int main(int argc, char** argv)
{
    pid_t child_pid;

    if(argc < 2)
    {
        fprintf(stderr, "Expected a program name as argument\n");
        return -1;
    }

    child_pid = fork(); 

    if (child_pid == 0)
        run_target(argv[1]);
    else if (child_pid > 0)
        run_debugger(child_pid);
    else 
    {
        perror("fork");
        return -1;
    }

    return 0;
}


void run_target(const char* programname)
{
    printf("target started. will run '%s'\n", programname);

    /* Allow tracing of this process */
    if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
    {
        perror("ptrace");
        return;
    }

    /* Replace this process's image with the given program */
    execl(programname, programname, 0);
}

void run_debugger(pid_t child_pid)
{
    int wait_status;
    unsigned icounter = 0;
    printf("debugger started\n");

    /* Wait for child to stop on its first instruction */
    wait(&wait_status);

    while (WIFSTOPPED(wait_status)) 
    {
        icounter++;

        struct user_pt_regs regs;
        struct iovec io;
        io.iov_base = &regs;
        io.iov_len = sizeof(regs);


        if (ptrace(PTRACE_GETREGSET, child_pid, (void*)NT_PRSTATUS, (void*)&io) == -1)
            printf("BAD REGISTER REQUEST\n");

        unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.pc, 0);

        printf("icounter = %u.  PCP = 0x%08x.  instr = 0x%08x\n", icounter, regs.pc, instr);

        /* Make the child execute another instruction */
        if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) 
        {
            perror("ptrace");
            return;
        }

        /* Wait for child to stop on its next instruction */
        wait(&wait_status);
    }

    printf("the child executed %u instructions\n", icounter);
}