Search code examples
linuxbashexit-codeperf

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


I have to get statistics of some programs with perf stat i.e

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

I also have to get exit codes of those programs, as they will not always exit with 0. Let's say I have simple program that will return SIGSEGV:

main(){*(int*)0=0;}

Now when I run it I get:

$ ./a.out Segmentation fault (core dumped) $ echo $? 139

When I run it with perf however i get

$ perf stat -o stat.log ./a.out ./a.out: Segmentation fault $ echo $? 0

I get 0, as if program finished without errors.

How can i get exit code of of a.out when I run it with perf stat?

EDIT: a.out is blackbox, I can't modify it in any way.


Solution

  • Short Answer:

    perf stat automatically returns the exit code of the program that it is running. The problem is that you are trying to get the return code from your shell.

    Longer answer:

    What is happening in your example is that when you run your ./a.out program it produces a segfault. Bash (or whatever your shell is) catches the segfault and it sets the return value appropriately.

    When you run the command with perf stat is does not set the exit code for a program that segfaults. So instead you get a 0 exit code for perf itself exiting correctly (it could be misleading for perf to set the exit code to that of segfault because perf didn't segfault in this case).

    To get the segfault (or other abnormal termination) exit code results you can use a helper script to get the return code from your shell and then return that to perf. For example the following worked for me:

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

    Using this wrapper.sh script to call your ./a.out program using perf stat gives the desired return code of 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