1#!/bin/sh
2#
3# american fuzzy lop - status check tool
4# --------------------------------------
5#
6# Written and maintained by Michal Zalewski <lcamtuf@google.com>
7#
8# Copyright 2015 Google Inc. All rights reserved.
9#
10# Licensed under the Apache License, Version 2.0 (the "License");
11# you may not use this file except in compliance with the License.
12# You may obtain a copy of the License at:
13#
14#   http://www.apache.org/licenses/LICENSE-2.0
15#
16# This tool summarizes the status of any locally-running synchronized
17# instances of afl-fuzz.
18#
19
20echo "status check tool for afl-fuzz by <lcamtuf@google.com>"
21echo
22
23if [ "$1" = "-s" ]; then
24
25  SUMMARY_ONLY=1
26  DIR="$2"
27
28else
29
30  unset SUMMARY_ONLY
31  DIR="$1"
32
33fi
34
35if [ "$DIR" = "" ]; then
36
37  echo "Usage: $0 [ -s ] afl_sync_dir" 1>&2
38  echo 1>&2
39  echo "The -s option causes the tool to skip all the per-fuzzer trivia and show" 1>&2
40  echo "just the summary results. See docs/parallel_fuzzing.txt for additional tips." 1>&2
41  echo 1>&2
42  exit 1
43
44fi
45
46cd "$DIR" || exit 1
47
48if [ -d queue ]; then
49
50  echo "[-] Error: parameter is an individual output directory, not a sync dir." 1>&2
51  exit 1
52
53fi
54
55CUR_TIME=`date +%s`
56
57TMP=`mktemp -t .afl-whatsup-XXXXXXXX` || exit 1
58
59ALIVE_CNT=0
60DEAD_CNT=0
61
62TOTAL_TIME=0
63TOTAL_EXECS=0
64TOTAL_EPS=0
65TOTAL_CRASHES=0
66TOTAL_PFAV=0
67TOTAL_PENDING=0
68
69if [ "$SUMMARY_ONLY" = "" ]; then
70
71  echo "Individual fuzzers"
72  echo "=================="
73  echo
74
75fi
76
77for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
78
79  sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/="/;s/$/"/' "$i" >"$TMP"
80  . "$TMP"
81
82  RUN_UNIX=$((CUR_TIME - start_time))
83  RUN_DAYS=$((RUN_UNIX / 60 / 60 / 24))
84  RUN_HRS=$(((RUN_UNIX / 60 / 60) % 24))
85
86  if [ "$SUMMARY_ONLY" = "" ]; then
87
88    echo ">>> $afl_banner ($RUN_DAYS days, $RUN_HRS hrs) <<<"
89    echo
90
91  fi
92
93  if ! kill -0 "$fuzzer_pid" 2>/dev/null; then
94
95    if [ "$SUMMARY_ONLY" = "" ]; then
96
97      echo "  Instance is dead or running remotely, skipping."
98      echo
99
100    fi
101
102    DEAD_CNT=$((DEAD_CNT + 1))
103    continue
104
105  fi
106
107  ALIVE_CNT=$((ALIVE_CNT + 1))
108
109  EXEC_SEC=$((execs_done / RUN_UNIX))
110  PATH_PERC=$((cur_path * 100 / paths_total))
111
112  TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX))
113  TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
114  TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
115  TOTAL_CRASHES=$((TOTAL_CRASHES + unique_crashes))
116  TOTAL_PENDING=$((TOTAL_PENDING + pending_total))
117  TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))
118
119  if [ "$SUMMARY_ONLY" = "" ]; then
120
121    echo "  cycle $((cycles_done + 1)), lifetime speed $EXEC_SEC execs/sec, path $cur_path/$paths_total (${PATH_PERC}%)"
122
123    if [ "$unique_crashes" = "0" ]; then
124      echo "  pending $pending_favs/$pending_total, coverage $bitmap_cvg, no crashes yet"
125    else
126      echo "  pending $pending_favs/$pending_total, coverage $bitmap_cvg, crash count $unique_crashes (!)"
127    fi
128
129    echo
130
131  fi
132
133done
134
135rm -f "$TMP"
136
137TOTAL_DAYS=$((TOTAL_TIME / 60 / 60 / 24))
138TOTAL_HRS=$(((TOTAL_TIME / 60 / 60) % 24))
139
140test "$TOTAL_TIME" = "0" && TOTAL_TIME=1
141
142echo "Summary stats"
143echo "============="
144echo
145echo "       Fuzzers alive : $ALIVE_CNT"
146
147if [ ! "$DEAD_CNT" = "0" ]; then
148  echo "      Dead or remote : $DEAD_CNT (excluded from stats)"
149fi
150
151echo "      Total run time : $TOTAL_DAYS days, $TOTAL_HRS hours"
152echo "         Total execs : $((TOTAL_EXECS / 1000 / 1000)) million"
153echo "    Cumulative speed : $TOTAL_EPS execs/sec"
154echo "       Pending paths : $TOTAL_PFAV faves, $TOTAL_PENDING total"
155
156if [ "$ALIVE_CNT" -gt "1" ]; then
157  echo "  Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)"
158fi
159
160echo "       Crashes found : $TOTAL_CRASHES locally unique"
161echo
162
163exit 0
164