在Linux中检测system()函数返回值的含义

4
当我在Linux上运行C++代码并使用system(COMMAND)函数执行命令时,每次调用system(COMMAND)的返回值都不同。我们有没有办法通过system(COMMAND)函数的返回值检测分段错误或异常终止?
例如,当我使用system函数执行命令后出现分段错误时,我确认该函数的返回值为35584。然而,我不知道该返回值的含义,也不确定所有可能的分段错误是否都返回35584。是否有一种方法可以检测遇到分段错误或异常终止时所有可能的返回值?

你可以使用较低级别的 forkpipedup2closeexecvewaitpid 系统调用。然后,waitpid 将给出正确的状态。你还可以使用一些特定于库的函数(例如,GtkQt 都提供了用于异步进程的函数)。 - Basile Starynkevitch
4个回答

6

man 3 system指的是返回值的含义,需要参考man 2 wait。后者页面描述了几个可用于此值的宏,特别是WIFSIGNALED(status)WTERMSIG(status)。这就是你可以用来检查分段故障或其他信号终止的方法。


2
#include <cstdlib>
#include <iostream>

int main()
{
  const int result = system("./core_dump"); // core_dump only calls abort()
  std::cout << "result=" << result << '\n';
  std::cout << "Terminated by signal: " << (WIFSIGNALED(result) ? "yes" : "no") << '\n';
  std::cout << "Exited normally: " << (WIFEXITED(result) ? "yes" : "no") << '\n';
  return 0;
}

输出结果(在Ubuntu 12.10上):

Aborted (core dumped)
result=34304
Terminated by signal: no
Exited normally: yes

./core_dump 打印出 exited normally: yes 可能会让人感到惊讶。尽管 ./core_dump 失败了,但 system 返回运行命令的 /bin/sh -c 进程的退出码,该进程正常退出。

相比之下,调用 system("/bin/kill -9 $$") 而不是 system("./core_dump") 会产生以下输出:

result=9
Terminated by signal: yes
Exited normally: no

关于退出代码还有一个重要说明。在core_dump的例子中,返回了退出代码34304。首先,我们需要将其向左移动8位。结果为35304 >> 8 == 134,这是被中止信号杀死的作业的退出代码。如果由于段错误而失败,我们将得到139。 这里提供了一个关于退出代码的概述链接。
最后,这是用于测试的core_dump源代码:
#include <cstdlib>

int main() {
  abort();
  return 0;
}

1
因为system返回运行命令的/bin/sh -c进程的退出代码,而该sh即使由命令启动的程序崩溃也不会核心转储。 - Basile Starynkevitch

1

本问题讨论了Linux退出代码:Linux中是否有任何标准的退出状态码?

IIRC,system()的返回值应该对应于生成的进程的退出代码,但这似乎与您的观察相矛盾。奇怪。我会进行测试。

编辑:观察结果:

  1. 我可以确认您对system()的返回值。
  2. 请注意,35585 == 139 << 8。139是Linux中一个段错误进程的退出代码

接下来要检查glibc源代码以获得权威答案...


0

对于任意的命令?并不完全是这样。每个程序都有自己赋予退出代码含义的权利。唯一可以假设的是0表示成功,但即使如此也只是惯例而非保证。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接