4

別のプログラムがクラッシュしないことをテストするために使用している C++ プログラムがあります。親コード (「parentProg」と呼びます) は次のようになります。

int run(const char * command)
{
  ...

  int retCode = system(command);
  printf("Code is %d\n",retCode);
  if(retCode == 134) //128 + SIGABORT
  {
    // Record error conditions
    ...
  }
}

command 変数には、テストされるプログラムが含まれます (これを「childProg」と呼びます)。以前の Linux ディストリビューションでは、このコードは期待どおりに機能していました。a.out がクラッシュしたり、アサーションにヒットした場合、134 が返され、エラー処理コードが実行されます。しかし、新しい Linux ディストリビューションにアップグレードした後は、そうではなくなりました。代わりに、GDB または nemiver を使用して生成されたプログラムとして実行すると、戻りコード 6 が表示されます。奇妙なことに、子プログラムを単独で実行するか、DDD を使用して実行すると、134 に戻ります。

次のテストでは、childProg を次のコードのみに変更しました。

#include <assert.h>

int main(int argc, char * argv[])
{
  assert(0);
  return 0;
}

childProg 自体

[user@localhost multi]$ ./childProg 
childProg: temp.cpp:5: int main(int, char **): Assertion `0' failed.
Abort
[user@localhost multi]$ echo $?
134

childProg を生成する parentProg

[user@localhost multi]$ ./parentProg 1 o
Running 1 times
childProg: temp.cpp:5: int main(int, char **): Assertion `0' failed.
Code is 6
Done 0
[user@localhost multi]$ 

GDBあり

(gdb) run
Starting program: parentProg 1 o
Running 1 times
Detaching after fork from child process 3311.
childProg: temp.cpp:5: int main(int, char **): Assertion `0' failed.
Code is 6
Done 0
[Inferior 1 (process 3295) exited normally]
(gdb) 

DDDあり

(gdb) run 1 o
Starting program: parentProg 1 o
Running 1 times
Detaching after fork from child process 3336.
childProg: temp.cpp:5: int main(int, char **): Assertion `0' failed.
Code is 134
Done 0
[Inferior 1 (process 3319) exited normally]
(gdb) 

これは期待どおりに機能します

[me@localhost multi]$ /bin/sh -c ./childProg
childProg: temp.cpp:5: int main(int, char **): Assertion `0' failed.
Abort
[me@localhost multi]$ echo $?
134

ここで何が起こっている可能性がありますか?終了コードをチェックする以外に、クラッシュ/セグメンテーション違反/アサーションをチェックするより良い方法はありますか?

4

2 に答える 2

6

<sys/wait.h> ヘッダー ファイルには、リターン コードを分析するためのマクロが含まれています。

終了の理由を確認するには、次のようにします。

#include <stdio.h>
#include <sys/wait.h>

...

void run(const char *command)
{
    int retcode = system(command);

    if (WIFEXITED(retcode))
    {
        int status = WEXITSTATUS(retcode);
        if (status)
        {
            printf("Exited normally with FAILURE status of %d!\n", status);
        }
        else
        {
            printf("Exited normally with SUCCESS(0) status!\n");
        }
    }
    else if (WIFSIGNALED(retcode))
    {
        int signal = WTERMSIG(retcode);
        printf("Abnormal termination - program crashed or was aborted with signal %d\n", signal);
    }

}

これらのマクロの説明については、「man waitpid」を参照してください。

于 2013-07-10T04:15:36.567 に答える
1

(134 = 6 | __WCOREFLAG)

見るman 2 wait

于 2013-07-01T04:29:15.543 に答える