如何获取使用 perf stat 运行的程序的退出代码?
Posted
技术标签:
【中文标题】如何获取使用 perf stat 运行的程序的退出代码?【英文标题】:How can I get exit code of program run with perf stat? 【发布时间】:2016-01-14 10:30:32 【问题描述】:我必须使用 perf stat 获取一些程序的统计信息,即
perf stat -o stat.log ./a.out
我还必须获取这些程序的退出代码,因为它们不会总是以 0 退出。假设我有一个简单的程序会返回 SIGSEGV:
main()*(int*)0=0;
现在当我运行它时,我得到:
$ ./a.out
Segmentation fault (core dumped)
$ echo $?
139
当我用 perf 运行它时,我得到了
$ perf stat -o stat.log ./a.out
./a.out: Segmentation fault
$ echo $?
0
我得到 0,好像程序完成没有错误。
当我使用 perf stat 运行 a.out 时,如何获得退出代码?
编辑:a.out 是黑盒,我不能以任何方式修改它。
【问题讨论】:
【参考方案1】:简答:
perf stat
自动返回它正在运行的程序的退出代码。问题是你试图从你的 shell 中获取返回码。
更长的答案:
您的示例中发生的情况是,当您运行 ./a.out
程序时,它会产生段错误。 Bash(或任何你的 shell)捕获段错误并适当地设置返回值。
当您使用perf stat
运行命令时,不会为出现段错误的程序设置退出代码。因此,您会得到一个 0 退出代码来表示 perf 本身正确退出(对于 perf 将退出代码设置为 segfault 的退出代码可能会产生误导,因为在这种情况下 perf 没有 segfault)。
要获得段错误(或其他异常终止)退出代码结果,您可以使用帮助脚本从 shell 获取返回代码,然后将其返回给 perf。例如以下对我有用:
#!/bin/bash
`/bin/bash -c "$@"`
使用此wrapper.sh
脚本调用您的./a.out
程序,使用perf stat
给出所需的返回码139
。
$ perf stat ./wrapper.sh ./a.out
Performance counter stats for './wrapper.sh ./a.out':
9.959972 task-clock (msec) # 0.766 CPUs utilized
5 context-switches # 0.502 K/sec
3 cpu-migrations # 0.301 K/sec
464 page-faults # 0.047 M/sec
16,413,813 cycles # 1.648 GHz
7,262,551 stalled-cycles-frontend # 44.25% frontend cycles idle
4,830,727 stalled-cycles-backend # 29.43% backend cycles idle
22,785,421 instructions # 1.39 insns per cycle
# 0.32 stalled cycles per insn
4,699,645 branches # 471.853 M/sec
124,437 branch-misses # 2.65% of all branches
0.013010875 seconds time elapsed
$ echo $?
139
【讨论】:
使用这个解决方案我可以获得退出代码,但是,我不会失去准确性,因为 perf 也会计算包装脚本的执行吗?从一些快速测量来看,我似乎得到了大约 3-4kk 的额外指令(我只检查了指令数,因为它现在对我来说最重要)。我将不得不检查这个值是否或多或少是恒定的,以及它在我的用例中是否重要。 经过一些测试,它看起来微不足道,我可以使用这个解决方案。【参考方案2】:您可能会得到 0 退出代码,因为 perf stat
已成功运行。
你应该在a.out
中获得退出代码,就在你正在执行的命令之后。
【讨论】:
OP 知道这是 什么 需要做的。问题是如何去做。 我无法修改 a.out。以上是关于如何获取使用 perf stat 运行的程序的退出代码?的主要内容,如果未能解决你的问题,请参考以下文章
perf stat 上的 subprocess.communicate 未返回预期的 stdout、stderr