如何获取使用 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-如何获取程序的当前运行时时钟

理解 perf stat 输出中的数字

perf stat 上的 subprocess.communicate 未返回预期的 stdout、stderr

perf 报告单个睡眠的多个 sched:sched_stat_sleep 事件

我如何使用 perf 来分析我的代码?

perf-perf stat用户层代码分析