调试时为什么生成的程序退出代码会发生变化?

时间:2013-07-01 04:12:38

标签: c++ c linux assert exit-code

我有一个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
    ...
  }
}

命令变量包含正在测试的程序(我们称之为'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

parentProg,它生成childProg

[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

这可能会发生什么?除了检查退出代码之外,还有更好的方法来检查崩溃/段错误/断言吗?

2 个答案:

答案 0 :(得分:6)

&lt; sys / wait.h&gt;头文件包含用于分析返回代码的宏。

要检查退出的原因,您可以执行以下操作:

#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”。

答案 1 :(得分:1)

(134 = 6 | __WCOREFLAG)

请参阅man 2 wait