2014-10-25 3 views
2

Я сделал следующий простой пример для чтения памяти из дочернего процесса, используя ptrace.Ребенок процесс не продолжает выполнение, когда ptrace'ing

Я хочу видеть значение по определенному адресу, 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; 
} 
+2

Как вы можете вызывать 'ptrace' с переменным числом параметров? – ooga

+0

Он компилирует/работает отлично, я решил, что ptrace дефолт оставшиеся значения 0 или NULL – spiffman

+0

Я должен был опубликовать это раньше, но @ooga это была именно проблема. По какой-то причине он позволяет мне скомпилировать и запустить с переменным числом параметров для ptrace, но он не выполняется, как ожидалось. Добавлены аргументы 0/NULL. – spiffman

ответ

1

Вы, кажется, не устанавливаете параметр PTRACE_O_TRACEEXEC. В противном случае SIGTRAP будет отправлен на трассировку при вызове exec; если он не подготовлен, действие по умолчанию - это завершение с дампом ядра.

+0

Я понимаю, что использование ptrace (PTRACE_TRACEME) ловушки трассировки на следующем вызове exec, но не должно ptrace (PTRACE_CONT, child) позволить ему возобновить выполнение? – spiffman

Смежные вопросы