如何使用 perf stat 获取程序 运行 的退出代码?

How can I get exit code of program run with perf stat?

我必须使用 perf stat 获取一些程序的统计信息,即

perf stat -o stat.log ./a.out

我还必须获取这些程序的退出代码,因为它们不会总是以 0 退出。假设我有一个简单的程序,它将 return 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 是黑盒,我无法以任何方式修改它。

您可能得到 0 退出代码,因为 perf stat 已成功完成 运行。 您应该在执行命令后立即在 a.out 中获得退出代码。

简答:

perf stat 自动 returns 程序的退出代码,它是 运行ning。问题是您正试图从 shell.

获取 return 代码

更长的答案:

您的示例中发生的情况是,当您 运行 您的 ./a.out 程序产生段错误时。 Bash(或者你的 shell 是什么)捕获段错误并适当地设置 return 值。

当您 运行 时,带有 perf stat 的命令不会为出现段错误的程序设置退出代码。因此,您得到的是 perf 本身正确退出的 0 退出代码(perf 将退出代码设置为 segfault 的退出代码可能会产生误导,因为在这种情况下 perf 没有出现段错误)。

要获取段错误(或其他异常终止)退出代码结果,您可以使用辅助脚本从 shell 获取 return 代码,然后 return 执行该代码.例如,以下对我有用:

#!/bin/bash
`/bin/bash -c "$@"`

使用此 wrapper.sh 脚本调用您的 ./a.out 程序,使用 perf stat 给出所需的 return 代码 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