0

セグメント違反エラーの子プロセスを監視しようとしていますが、うまくいきません。

私は常にABRT信号を受信します。

gdb はセグメント フォールトをキャッチできるようですが、コードの何が問題なのですか?

        pid_t child;
        int wstatus, signum;
        struct user_regs_struct regs;

        child = fork();
        if (child == 0)
        {
                ptrace(PTRACE_TRACEME, 0, NULL, NULL);
                char buf[10];
                // make it always crash
                strcpy (buf, "aaaaaaabbbbbbbbbbbaaaaaaaaaaaaaaaa");
                printf ("Buf is %s\n", buf);

                exit(0);
        }

        while(1)
        {
                wait(&wstatus);
                if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus))
                        break;

                signum = WSTOPSIG(wstatus);
                ptrace(PTRACE_GETREGS, child, NULL, &regs);

                printf ("signal: %d, eip: 0x%08lx\n", signum, regs.eip);
                ptrace(PTRACE_CONT, child, NULL, signum);
        }
4

1 に答える 1

2

私のコードの何が問題なのですか

子がシグナル状態になると、コードはループから抜け出します ( WIFSIGNALED)。シグナルをキャッチすることを期待しているので (ほとんどSIGSEGVの場合)、子がシグナルを受け取ったときにループから抜け出すべきではありませんか?

私はあなたのコードをもう少し見ました。なぜあなたの子供が墜落たのかはまったく明らかではありません。おそらく、あなたはそれを構築してい-fstack-protectorますか?

これは完全にコンパイル可能なテストケースです(質問に入れる必要exitがあります)、クラッシュします(注:子から削除されました):

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

int main()
{
    pid_t child;
    int wstatus, signum;
    struct user_regs_struct regs;

    child = fork();
    if (child == 0)
    {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        char buf[10];
        // make it always crash
        strcpy (buf, "aaaaaaabbbbbbbbbbbaaaaaaaaaaaaaaaa");

        printf ("Buf is %s\n", buf);
    }

    while(1)
    {
        wait(&wstatus);
        if (WIFEXITED(wstatus))
            break;

        signum = WSTOPSIG(wstatus);
        ptrace(PTRACE_GETREGS, child, NULL, &regs);

        printf ("signal: %d, eip: 0x%08lx\n", signum, regs.eip);
        ptrace(PTRACE_CONT, child, NULL, signum);
    }
    return wstatus;
}

そして無限ループになりました

通常、無限ループが発生するはずです。子を再開すると、現在の命令が再実行され、まったく同じ信号が再度トリガーされます。

それは私のシステム上の上記のプログラムで起こっていることではなく、現在私が観察していることを説明することはできません:

$ ./a.out
Buf is aaaaaaabbbbbbbbbbbaaaaaaaaaaaaaaaa
signal: 159, eip: 0x08049ff4
signal: 159, eip: 0x08049ff4
...
signal: 159, eip: 0x08049ff4
*** stack smashing detected ***: ./a.out terminated
signal: 11, eip: 0xf759fb19
signal: 0, eip: 0xf759fb19
signal: 0, eip: 0xf759fb19
...
于 2013-04-30T04:38:11.270 に答える