![为什么在出现 SIGABRT 的情况下,“/usr/bin/time”会报告格式为“%x”的错误退出状态?](https://linux22.com/image/1192087/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E5%87%BA%E7%8E%B0%20SIGABRT%20%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E2%80%9C%2Fusr%2Fbin%2Ftime%E2%80%9D%E4%BC%9A%E6%8A%A5%E5%91%8A%E6%A0%BC%E5%BC%8F%E4%B8%BA%E2%80%9C%EF%BC%85x%E2%80%9D%E7%9A%84%E9%94%99%E8%AF%AF%E9%80%80%E5%87%BA%E7%8A%B6%E6%80%81%EF%BC%9F.png)
我用/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/sh
是dash
,但根据链接的 U&L 帖子,它在这方面的行为应该与 bash 相同。由于dash
比 bash 轻量得多,您可以在此处使用sh -c
而不是bash -c
,并且对指标的影响较小。