1

大学のクラス用に簡単なデバッガーを作成していますが、SIGINT の処理に問題があります。

私がやりたいのは、デバッガープロセス(今後はPDB)がSIGINTシグナルを受け取り、それを子プロセス(PDBによって実際にデバッグされているプロセス)に渡すことです。

私はこれをやっています:

pid_t childid;

void catch_sigint(int sig)
{
    signal(SIGINT,SIG_DFL);
    kill(childid,sig);
}

int debuger (char *address, parm *vars)
{
    int ignore=1;
    int status;

    childid = fork();
    signal(SIGINT,catch_sigint);
    if(childid==0)
    {
        ptrace(PTRACE_TRACEME,0, NULL,NULL);
        if(execve(address,NULL,NULL)==-1)
        {
            perror("ERROR occured when trying to create program to trace\n");
            exit(1);
        }
    }
    else
    {
        int f_time=1;

        while(1)
        {
            long system_call;

            wait(&status);
            if(WIFEXITED(status))break;
            if(WIFSIGNALED(status))break;

            system_call = ptrace(PTRACE_PEEKUSER,childid, 4 * ORIG_EAX, NULL);

            if(!strcmp(vars->category,"process-control") || !strcmp(vars->category,"all"))      
                ignore = pr_calls(system_call,ignore,limit,childid,vars->mode); //function that takes the system call that is made and prints info about it
            if(!strcmp(vars->category,"file-management") || !strcmp(vars->category,"all"))
                ignore = fl_calls(system_call,ignore,limit,childid,vars->mode);

            if(f_time){ignore=1;f_time=0;}
            ptrace(PTRACE_SYSCALL,childid, NULL, NULL);
        }        
    }
    signal(SIGINT,SIG_DFL);
    return 0;
}

このプログラムは、子プロセスを実行して fork し、プログラムを実行してそのシステム コールをトレースします。信号が届かないときは問題なく動作します。

しかし、いくつかのトレースの途中で ctrl+c を押すと、子プロセスが停止し、PDB が続行して停止することが予想されます (この行のためにif(WIFSIGNALED(status))break;. それは決して起こりません. トレースするプログラムは、システムコールを続行して印刷します.

トレース プログラムは次のとおりです。

#include <stdio.h>

int main(void)
{
    for(;;) printf("HELLO WORLD\n");        
    return 0;
}

そのプログラムは、ctrl+c を押した後でも HELLO WORLD を出力し続けます。

また、ctrl+c の後に ptrace が与えるシステム コールは -38 であり、待機中のステータスは、1407 (通常の値だと思います) から 639 への信号の後、1 回だけ変化し、次の信号で 1407 に戻ることも観察しました。待つ。

それで、私はその中で何が間違っていますか?

4

1 に答える 1

0

この行にある問題:

ptrace(PTRACE_SYSCALL,childid, NULL, NULL);

それはそのようでなければなりません:

ptrace(PTRACE_SYSCALL,childid, NULL, signal_variable);

signal_variableハンドラーとデバッガーがそれを見ることができるように、グローバルスコープで宣言された int はどこにありますか。開始値は 0 です。

シグナルハンドラーはシグナルを受け取り、この変数に渡します。次のループで、ptrace がトレースプログラムに継続するように命令すると、シグナルも送信されます。これは、プログラムをトレースするときに、トレースがシグナルを受信すると実行を停止し、ptrace を介してトレーサからシグナルを処理するためのさらなる命令を待機するために発生します。

于 2013-04-20T20:09:55.410 に答える