xref: /aosp_15_r20/external/AFLplusplus/test/test-performance.sh (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1#!/bin/bash
2
3# if you want a specific performance file (e.g. to compare features to another)
4# you can set the AFL_PERFORMANCE_FILE environment variable:
5FILE=$AFL_PERFORMANCE_FILE
6# otherwise we use ~/.afl_performance
7test -z "$FILE" && FILE=.afl_performance
8
9test -e $FILE || {
10  echo Warning: This script measure the performance of AFL++ and saves the result for future comparisons into $FILE
11  echo Press ENTER to continue or CONTROL-C to abort
12  read IN
13}
14
15test -e ./test-performance.sh || { echo Error: this script must be run from the directory in which it lies. ; exit 1 ; }
16
17export AFL_QUIET=1
18export AFL_PATH=`pwd`/..
19
20unset AFL_EXIT_WHEN_DONE
21unset AFL_EXIT_ON_TIME
22unset AFL_SKIP_CPUFREQ
23unset AFL_DEBUG
24unset AFL_HARDEN
25unset AFL_USE_ASAN
26unset AFL_USE_MSAN
27unset AFL_CC
28unset AFL_PRELOAD
29unset AFL_GCC_INSTRUMENT_FILE
30unset AFL_LLVM_INSTRUMENT_FILE
31unset AFL_LLVM_INSTRIM
32unset AFL_LLVM_LAF_SPLIT_SWITCHES
33unset AFL_LLVM_LAF_TRANSFORM_COMPARES
34unset AFL_LLVM_LAF_SPLIT_COMPARES
35
36# on OpenBSD we need to work with llvm from /usr/local/bin
37test -e /usr/local/bin/opt && {
38  export PATH=/usr/local/bin:${PATH}
39}
40# on MacOS X we prefer afl-clang over afl-gcc, because
41# afl-gcc does not work there
42test `uname -s` = 'Darwin' -o `uname -s` = 'FreeBSD' && {
43  AFL_GCC=afl-clang
44  CC=clang
45} || {
46  AFL_GCC=afl-gcc
47  CC=gcc
48}
49
50ECHO="printf %b\\n"
51$ECHO \\101 2>&1 | grep -qE '^A' || {
52  ECHO=
53  test -e /bin/printf && {
54    ECHO="/bin/printf %b\\n"
55    $ECHO '\\101' 2>&1 | grep -qE '^A' || ECHO=
56  }
57}
58test -z "$ECHO" && { printf Error: printf command does not support octal character codes ; exit 1 ; }
59
60GREY="\\033[1;90m"
61BLUE="\\033[1;94m"
62GREEN="\\033[0;32m"
63RED="\\033[0;31m"
64YELLOW="\\033[1;93m"
65RESET="\\033[0m"
66
67MEM_LIMIT=500
68
69touch $FILE || { echo Error: can not write to $FILE ; exit 1 ; }
70
71echo Warning: this script is setting performance parameters with afl-system-config
72sleep 1
73afl-system-config > /dev/null 2>&1
74echo Performance settings applied.
75echo
76
77$ECHO "${RESET}${GREY}[*] starting AFL++ performance test framework ..."
78
79$ECHO "$BLUE[*] Testing: ${AFL_GCC}"
80GCC=x
81test -e ../${AFL_GCC} -a -e ../afl-fuzz && {
82  ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1
83  test -e test-instr.plain && {
84    $ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded"
85    mkdir -p in
86    echo 0 > in/in
87    $ECHO "$GREY[*] running afl-fuzz for ${AFL_GCC} for 30 seconds"
88    {
89      ../afl-fuzz -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-gcc -- ./test-instr.plain
90    } >>errors 2>&1
91    test -n "$( ls out-gcc/default/queue/id:000002* 2> /dev/null )" && {
92      GCC=`grep execs_done out-gcc/default/fuzzer_stats | awk '{print$3}'`
93    } || {
94        echo CUT----------------------------------------------------------------
95        cat errors
96        echo CUT----------------------------------------------------------------
97      $ECHO "$RED[!] afl-fuzz is not working correctly with ${AFL_GCC}"
98    }
99    rm -rf in out-gcc errors test-instr.plain
100  } || $ECHO "$RED[!] ${AFL_GCC} instrumentation failed"
101} || $ECHO "$YELLOW[-] afl is not compiled, cannot test"
102
103$ECHO "$BLUE[*] Testing: llvm_mode"
104LLVM=x
105test -e ../afl-clang-fast -a -e ../afl-fuzz && {
106  ../afl-clang-fast -o test-instr.llvm ../test-instr.c > /dev/null 2>&1
107  test -e test-instr.llvm && {
108    $ECHO "$GREEN[+] llvm_mode compilation succeeded"
109    mkdir -p in
110    echo 0 > in/in
111    $ECHO "$GREY[*] running afl-fuzz for llvm_mode for 30 seconds"
112    {
113      ../afl-fuzz -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-llvm -- ./test-instr.llvm
114    } >>errors 2>&1
115    test -n "$( ls out-llvm/default/queue/id:000002* 2> /dev/null )" && {
116      LLVM=`grep execs_done out-llvm/default/fuzzer_stats | awk '{print$3}'`
117    } || {
118        echo CUT----------------------------------------------------------------
119        cat errors
120        echo CUT----------------------------------------------------------------
121      $ECHO "$RED[!] afl-fuzz is not working correctly with llvm_mode"
122    }
123    rm -rf in out-llvm errors test-instr.llvm
124  } || $ECHO "$RED[!] llvm_mode instrumentation failed"
125} || $ECHO "$YELLOW[-] llvm_mode is not compiled, cannot test"
126
127$ECHO "$BLUE[*] Testing: gcc_plugin"
128GCCP=x
129test -e ../afl-gcc-fast -a -e ../afl-fuzz && {
130  ../afl-gcc-fast -o test-instr.gccp ../test-instr.c > /dev/null 2>&1
131  test -e test-instr.gccp && {
132    $ECHO "$GREEN[+] gcc_plugin compilation succeeded"
133    mkdir -p in
134    echo 0 > in/in
135    $ECHO "$GREY[*] running afl-fuzz for gcc_plugin for 30 seconds"
136    {
137      ../afl-fuzz -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-gccp -- ./test-instr.gccp
138    } >>errors 2>&1
139    test -n "$( ls out-gccp/default/queue/id:000002* 2> /dev/null )" && {
140      GCCP=`grep execs_done out-gccp/default/fuzzer_stats | awk '{print$3}'`
141    } || {
142        echo CUT----------------------------------------------------------------
143        cat errors
144        echo CUT----------------------------------------------------------------
145      $ECHO "$RED[!] afl-fuzz is not working correctly with gcc_plugin"
146    }
147    rm -rf in out-gccp errors test-instr.gccp
148  } || $ECHO "$RED[!] gcc_plugin instrumentation failed"
149} || $ECHO "$YELLOW[-] gcc_plugin is not compiled, cannot test"
150
151$ECHO "$BLUE[*] Testing: qemu_mode"
152QEMU=x
153test -e ../afl-qemu-trace -a -e ../afl-fuzz && {
154  $CC -o test-instr.qemu ../test-instr.c > /dev/null 2>&1
155  test -e test-instr.qemu && {
156    $ECHO "$GREEN[+] native compilation with cc succeeded"
157    mkdir -p in
158    echo 0 > in/in
159    $ECHO "$GREY[*] running afl-fuzz for qemu_mode for 30 seconds"
160    {
161      ../afl-fuzz -Q -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-qemu -- ./test-instr.qemu
162    } >>errors 2>&1
163    test -n "$( ls out-qemu/default/queue/id:000002* 2> /dev/null )" && {
164      QEMU=`grep execs_done out-qemu/default/fuzzer_stats | awk '{print$3}'`
165    } || {
166        echo CUT----------------------------------------------------------------
167        echo ../afl-fuzz -Q -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-qemu -- ./test-instr.qemu
168        cat errors
169        echo CUT----------------------------------------------------------------
170      $ECHO "$RED[!] afl-fuzz is not working correctly with qemu_mode"
171    }
172    rm -rf in out-qemu errors test-instr.qemu
173  } || $ECHO "$RED[!] qemu_mode instrumentation failed"
174} || $ECHO "$YELLOW[-] qemu_mode is not compiled, cannot test"
175
176LOW_GCC=
177HIGH_GCC=
178LAST_GCC=
179LOW_LLVM=
180HIGH_LLVM=
181LAST_LLVM=
182LOW_GCCP=
183HIGH_GCCP=
184LAST_GCCP=
185LOW_QEMU=
186HIGH_QEMU=
187LAST_QEMU=
188
189test -s $FILE && {
190  while read LINE; do
191    G=`echo $LINE | awk '{print$1}'`
192    L=`echo $LINE | awk '{print$2}'`
193    P=`echo $LINE | awk '{print$3}'`
194    Q=`echo $LINE | awk '{print$4}'`
195    test "$G" = x && G=
196    test "$L" = x && L=
197    test "$P" = x && P=
198    test "$Q" = x && Q=
199    test -n "$G" && LAST_GCC=$G
200    test -n "$L" && LAST_LLVM=$L
201    test -n "$P" && LAST_GCCP=$P
202    test -n "$Q" && LAST_QEMU=$Q
203    test -n "$G" -a -z "$LOW_GCC" && LOW_GCC=$G || {
204      test -n "$G" -a "$G" -lt "$LOW_GCC" 2> /dev/null && LOW_GCC=$G
205    }
206    test -n "$L" -a -z "$LOW_LLVM" && LOW_LLVM=$L || {
207      test -n "$L" -a "$L" -lt "$LOW_LLVM" 2> /dev/null && LOW_LLVM=$L
208    }
209    test -n "$P" -a -z "$LOW_GCCP" && LOW_GCCP=$P || {
210      test -n "$P" -a "$P" -lt "$LOW_GCCP" 2> /dev/null && LOW_GCCP=$P
211    }
212    test -n "$Q" -a -z "$LOW_QEMU" && LOW_QEMU=$Q || {
213      test -n "$Q" -a "$Q" -lt "$LOW_QEMU" 2> /dev/null && LOW_QEMU=$Q
214    }
215    test -n "$G" -a -z "$HIGH_GCC" && HIGH_GCC=$G || {
216      test -n "$G" -a "$G" -gt "$HIGH_GCC" 2> /dev/null && HIGH_GCC=$G
217    }
218    test -n "$L" -a -z "$HIGH_LLVM" && HIGH_LLVM=$L || {
219      test -n "$L" -a "$L" -gt "$HIGH_LLVM" 2> /dev/null && HIGH_LLVM=$L
220    }
221    test -n "$P" -a -z "$HIGH_GCCP" && HIGH_GCCP=$P || {
222      test -n "$P" -a "$P" -gt "$HIGH_GCCP" 2> /dev/null && HIGH_GCCP=$P
223    }
224    test -n "$Q" -a -z "$HIGH_QEMU" && HIGH_QEMU=$Q || {
225      test -n "$Q" -a "$Q" -gt "$HIGH_QEMU" 2> /dev/null && HIGH_QEMU=$Q
226    }
227  done < $FILE
228  $ECHO "$YELLOW[!] Reading saved data from $FILE completed, please compare the results:"
229  $ECHO "$BLUE[!] afl-cc: lowest=$LOW_GCC highest=$HIGH_GCC last=$LAST_GCC current=$GCC"
230  $ECHO "$BLUE[!] llvm_mode: lowest=$LOW_LLVM highest=$HIGH_LLVM last=$LAST_LLVM current=$LLVM"
231  $ECHO "$BLUE[!] gcc_plugin: lowest=$LOW_GCCP highest=$HIGH_GCCP last=$LAST_GCCP current=$GCCP"
232  $ECHO "$BLUE[!] qemu_mode: lowest=$LOW_QEMU highest=$HIGH_QEMU last=$LAST_QEMU current=$QEMU"
233} || {
234  $ECHO "$YELLOW[!] First run, just saving data"
235  $ECHO "$BLUE[!] afl-gcc=$GCC  llvm_mode=$LLVM  gcc_plugin=$GCCP  qemu_mode=$QEMU"
236}
237echo "$GCC $LLVM $GCCP $QEMU" >> $FILE
238$ECHO "$GREY[*] done."
239$ECHO "$RESET"
240