2012-05-04 7 views
4

それが実行されている間、私はプログラムをトレースしようとしている:ptrace(PTRACE_ATTACH, ...)ptrace(PTRACE_SINGLESTEP, ...)、などと...ptrace_detach、SIGINTおよびトレース/ブレークポイントトラップ(コアダンプ)

すべてが正常であると思われるが、私は辞めたとき私のトレースプログラムCTRL-Cで、トレースしたプログラムから(PTRACE_DETACHと)デタッチしたいと思います。このアクションを実行すると、トレースされたプログラムはエラーTrace/BPT trap (core dumped)でクラッシュします。

私の質問はトレースされたプログラムをクラッシュさせることなく適切に切り離すにはどうすればいいですか?ここで

SIGINT信号をキャッチされた機能である:

void sig_int() 
{ 
    if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) 
     my_perror("ptrace/DETACH", strerror(errno)); 
} 

EDIT:

ここではいくつかの他のコードです:

if ((ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) == -1))                         
    my_perror("ptrace/SINGLESTEP", strerror(errno)); 
if (wait4(pid, &(l->status), 0, 0) == -1) 
    my_perror("wait4", strerror(errno)); 
if (ptrace(PTRACE_GETREGS, pid, 0, &(l->reg)) == -1) 
    my_perror("ptrace/GETREGS", strerror(errno)); 
if ((l->opcode = ptrace(PTRACE_PEEKTEXT, pid, l->reg.rip, NULL)) == -1) 
    my_perror("ptrace/PEEKTEXT", strerror(errno)); 

これはどこ私のループの一部であります私はトレースの最初の部分を行う

+0

私は、エラーの原因を探し続け、切り離し前後でトレースされたプログラムを待つように試みましたが、同じエラーが発生するか、2つのプログラム間に無限ループがあります。 – Mindhavok

答えて

2

OK mここで問題が解決されたのは、SIGINTを捕捉する新しい関数です。

void   int_sig() 
{ 
    if (stop == 0) 
    { 
     printf("Interrupting!\n"); 
     ptrace(PTRACE_CONT, pid, NULL, NULL); 
     exit(0); 
    } 
} 

「stop」という名前のこの新しい変数は何ですか?

私のコードでは、私の後ろに行こうとしています。次の一回だけがシステムコールであるかどうかを知った直後に、一度だけ2回目にgetregsします。私はdo_next_stepのfounctionであったが、私の追跡プログラムを中断しようとしていた場合、これをトレースプログラムをクラッシュすること

void   do_step(t_list *l)                               
{ 
    if ((ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) == -1)) 
    my_perror("ptrace/SINGLESTEP", strerror(errno)); 
    if (wait4(pid, &(l->status), 0, 0) == -1) 
    my_perror("wait4", strerror(errno)); 
if (ptrace(PTRACE_GETREGS, pid, 0, &(l->reg)) == -1) 
    my_perror("ptrace/GETREGS", strerror(errno)); 
if ((l->opcode = ptrace(PTRACE_PEEKTEXT, pid, l->reg.rip, NULL)) == -1) 
    my_perror("ptrace/PEEKTEXT", strerror(errno)); 
} 

void   do_next_step(t_list *l, t_strace *t) 
{ 
    stop = 1; 
    if (ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) == -1 || 
     (wait4(pid, &(l->status), 0, 0) == -1)) 
    my_perror("ERROR", strerror(errno)); 
    if (!WIFSTOPPED(l->status) || WIFEXITED(l->status)) 
    { 
     printf("?\n"); 
     exit(0); 
    } 
if (ptrace(PTRACE_GETREGS, pid, 0, &(l->reg)) == -1) 
    my_perror("ptrace/GETREGS", strerror(errno)); 
if (t->ret == 1) 
    printf("%d\n", (int)l->reg.rax); 
    else 
    printf("%#lx\n", l->reg.rax); 
    stop = 0; 
} 

私が発見した:私は、システムコールの戻り値を取得するためにこれをやっていました!

私は 'do_next_step'関数にあった場合、int_sig()のアクションをスキップするフラグを設定します。

将来的に役立つだろうか興味深いことを望む!

私はこの問題を全部手伝ってくれてありがとう! 乾杯!

+0

+1自分で解決策を見つけるために:) –