2017-06-14 14 views
0

は:PTRACE_TRACEMEの範囲は何ですか?私はこのようなコードがある場合

void child() { 
    do_something(); 
    ptrace(PTRACE_TRACEME, 0, 0, 0); 
    do_some_other_things(); 
} 

を、その後do_something()親によってトレースされますか?

私はLinuxのマニュアルで見つけましたが、そのようなものはありませんでした。それは、これがトレースで呼び出されるべきだと言っただけです。

PTRACE_TRACEME

は、このプロセスは、その親によってトレースされるべきであることを示します。 プロセスは、親の がそれをトレースすることを期待していない場合、おそらくこの要求を行うべきではありません。 (PID、ADDR、そしてデータが は無視されます。)

答えて

1

がより良い説明のためHow Debuggers Work Part 1を参照してください、しかしtraceeが信号を受信するまでの要約で、いや、それはdo_something()関数をトレースしません。プロセスがフォーク(2)を呼び出し、その結果子供が を行う を持っていることによって、トレースを開始することができ

:あなたが引用され同じ男のptraceからのptraceコールの説明では

PTRACE_TRACEMEは、execve(2)の後に(通常は)続きます。あるいは、あるプロセスは、PTRACE_ATTACHまたはPTRACE_SEIZEを使用して別のプロセスをトレースすることを開始することができる。

信号がトレースされている間に、信号 が無視されている場合でも、信号が送信されるたびにトレースが停止します。 (例外はSIGKILLで、通常の効果があります)トレーサはwaitpid(2)の次回の呼び出し(または関連する "wait"システムコールの1つ)で通知されます です。 コールは、 トレース内の停止の原因を示す情報を含むステータス値を返します。

トレースがexecを呼び出すと、信号を受信するため、それが停止します。 、鐘や笛なしでトレーサープログラムmainer.cをillustraceする

//mainer.c 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/ptrace.h> 
#include <sys/user.h> 
#include <unistd.h> 

int main(int argc, char ** argv) 
{ 
     pid_t child_pid; 
     char * programname = argv[1]; 

     child_pid = fork(); 
     if (child_pid == 0) 
     { 
       ptrace(PTRACE_TRACEME, 0, 0, 0); 
       execl(programname, programname, NULL); 
     } 

     else if (child_pid > 0) 
     { 
      int status; 

      wait(&status); 

      while (WIFSTOPPED(status)) 
      { 
        struct user_regs_struct regs; 
        ptrace(PTRACE_GETREGS, child_pid, 0, &regs); 
        unsigned instr = (PTRACE_PEEKTEXT, child_pid, regs.eip, 0); 
        printf("EIP = 0x%08x, instr = 0x%08x\n", regs.eip, instr); 

        ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0); 

        wait(&status); 
      } 

     } 
} 

traceeが幹部ヒットすると、それが信号を受信して​​待っている親に制御を渡します。トレースする アセンブリプログラムは、単にあまりにも多くの有用なものを抽出するCプログラムをトレースするときにそこに起こっている:私たちは子供のようmainer.cを変更する場合

; hello.asm 
section .text 
    global _start 

_start: 
    mov edx,len1 
    mov ecx,hello1 
    mov ebx,1 
    mov eax,4 

    int 0x80 


    mov edx,len2 
    mov ecx,hello2 
    mov ebx,1 
    mov eax,4 

    int 0x80 

    mov eax,1 
    int 0x80 

section .data 
    hello1 db "Hello",0xA 
    len1 equ $ - hello1 

    hello2 db "World",0xA 
    len2 equ $ - hello2 

は、この、./mainer hello

EIP = 0x08048080, instr = 0x00000000 
EIP = 0x08048085, instr = 0x00000000 
EIP = 0x0804808a, instr = 0x00000000 
EIP = 0x0804808f, instr = 0x00000000 
EIP = 0x08048094, instr = 0x00000000 
Hello 
EIP = 0x08048096, instr = 0x00000000 
EIP = 0x0804809b, instr = 0x00000000 
EIP = 0x080480a0, instr = 0x00000000 
EIP = 0x080480a5, instr = 0x00000000 
EIP = 0x080480aa, instr = 0x00000000 
World 
EIP = 0x080480ac, instr = 0x00000000 
EIP = 0x080480b1, instr = 0x00000000 

を実行しますプロセスはexecの前にdo_something()を呼び出し、トレースの結果はまったく同じです。これはちょうど私がそれを修正したものです、結果が同じであることを好きなら、自分で確認できます。

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

int do_something(void)  //added this function 
{ 
     printf("Doing something"); 
     return 0; 
} 


int main(int argc, char ** argv) 
{ 
     pid_t child_pid; 
     char * programname = argv[1]; 

     child_pid = fork(); 
     if (child_pid == 0) 
     { 
       ptrace(PTRACE_TRACEME, 0, 0, 0); 
       do_something();  //added this function call 
       execl(programname, programname, NULL); 
     } 

     else if (child_pid > 0) 
     { 
      int status; 

      wait(&status); 

      while (WIFSTOPPED(status)) 
      { 
        struct user_regs_struct regs; 
        ptrace(PTRACE_GETREGS, child_pid, 0, &regs); 
        unsigned instr = (PTRACE_PEEKTEXT, child_pid, regs.eip, 0); 
        printf("EIP = 0x%08x, instr = 0x%08x\n", regs.eip, instr); 

        ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0); 

        wait(&status); 
      } 

     } 
} 

のでtraceeは、それが信号を受信するまで、それはexecを呼び出したときに何が起こるかである、止めるつもりはない、との関数を呼び出すことはtraceeための信号を生成しませんが、送信するために他の方法がありますトレースに信号を送り、トレースを開始しますが、それらはexecやwaitと同じくらい整然としたものではありません。

関連する問題