为什么在出现 SIGABRT 的情况下,“/usr/bin/time”会报告格式为“%x”的错误退出状态?

为什么在出现 SIGABRT 的情况下,“/usr/bin/time”会报告格式为“%x”的错误退出状态?

我用/usr/bin/time它来报告有关我正在运行的一组基准测试的信息。有趣的数据点是运行时、内存使用情况和退出状态。这工作正常,除非应用程序因未捕获的异常而失败,在这种情况下/usr/bin/time会报告0退出代码而不是实际的134

让我用该应用程序的一个玩具示例来说明这个问题:

#include <stdexcept>

int main(int argc, char** argv) {
    throw std::runtime_error("test"); // 1
    //return 134;                     // 2
}

以及以下调用: /usr/bin/time -f "%x" ./app ; echo $?

抛出错误(第 1 行未注释)会导致以下输出:

terminate called after throwing an instance of 'std::runtime_error'
  what():  test
Command terminated by signal 6
0
134

而实际返回退出状态(第 2 行未注释)是有效的:

Command exited with non-zero status 134
134
134

/usr/bin/time --version报告UNKNOWN版本,但我在 Ubuntu 20.04 和 22.04 上看到相同的行为。我怀疑这与 SIGABRT(信号 6)有关,但我找不到修复方法或对这种行为的解释。

在出现未捕获的异常时,如何/usr/bin/time报告正确的退出状态?

答案1

您在此处看到的退出状态 134 是 shell(在本例中可能是 bash)代表被终止的进程报告的值,表示该进程被信号终止。此报告的确切行为因 shell 而异,因此对于相同情况(例如,ksh),您会看到不同的值,而不是 134。整个情况在以下答案中进行了详尽解释这篇 Unix 和 Linux 文章

更糟糕的是,由于这是 shell 的一个功能,因此其他程序不应该这样做。该time命令反而会打印一条通知信号导致终止的消息 ( Command terminated by signal 6),但报告的是 0。

您可以改为使用 调用 shell time,并使用它来报告所需的退出状态。这可能会影响您可能关心的基准测试的其他指标,但应该可以工作:

/usr/bin/time -f "%x" bash -c './app; exit $'

在 Ubuntu 上,/bin/shdash,但根据链接的 U&L 帖子,它在这方面的行为应该与 bash 相同。由于dash比 bash 轻量得多,您可以在此处使用sh -c而不是bash -c,并且对指标的影响较小。

相关内容