• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    american fuzzy lop++ - stats related routines
3    ---------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Now maintained by Marc Heuse <mh@mh-sec.de>,
8                         Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
9                         Andrea Fioraldi <andreafioraldi@gmail.com>
10 
11    Copyright 2016, 2017 Google Inc. All rights reserved.
12    Copyright 2019-2022 AFLplusplus Project. All rights reserved.
13 
14    Licensed under the Apache License, Version 2.0 (the "License");
15    you may not use this file except in compliance with the License.
16    You may obtain a copy of the License at:
17 
18      https://www.apache.org/licenses/LICENSE-2.0
19 
20    This is the real deal: the program takes an instrumented binary and
21    attempts a variety of basic fuzzing tricks, paying close attention to
22    how they affect the execution path.
23 
24  */
25 
26 #include "afl-fuzz.h"
27 #include "envs.h"
28 #include <limits.h>
29 
30 /* Write fuzzer setup file */
31 
write_setup_file(afl_state_t * afl,u32 argc,char ** argv)32 void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
33 
34   u8 fn[PATH_MAX];
35   snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir);
36   FILE *f = create_ffile(fn);
37   u32   i;
38 
39   fprintf(f, "# environment variables:\n");
40   u32 s_afl_env = (u32)sizeof(afl_environment_variables) /
41                       sizeof(afl_environment_variables[0]) -
42                   1U;
43 
44   for (i = 0; i < s_afl_env; ++i) {
45 
46     char *val;
47     if ((val = getenv(afl_environment_variables[i])) != NULL) {
48 
49       fprintf(f, "%s=%s\n", afl_environment_variables[i], val);
50 
51     }
52 
53   }
54 
55   fprintf(f, "# command line:\n");
56 
57   size_t j;
58   for (i = 0; i < argc; ++i) {
59 
60     if (i) fprintf(f, " ");
61 #ifdef __ANDROID__
62     if (memchr(argv[i], '\'', sizeof(argv[i]))) {
63 
64 #else
65     if (index(argv[i], '\'')) {
66 
67 #endif
68 
69       fprintf(f, "'");
70       for (j = 0; j < strlen(argv[i]); j++)
71         if (argv[i][j] == '\'')
72           fprintf(f, "'\"'\"'");
73         else
74           fprintf(f, "%c", argv[i][j]);
75       fprintf(f, "'");
76 
77     } else {
78 
79       fprintf(f, "'%s'", argv[i]);
80 
81     }
82 
83   }
84 
85   fprintf(f, "\n");
86 
87   fclose(f);
88   (void)(afl_environment_deprecated);
89 
90 }
91 
92 /* load some of the existing stats file when resuming.*/
93 void load_stats_file(afl_state_t *afl) {
94 
95   FILE *f;
96   u8    buf[MAX_LINE];
97   u8 *  lptr;
98   u8    fn[PATH_MAX];
99   u32   lineno = 0;
100   snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir);
101   f = fopen(fn, "r");
102   if (!f) {
103 
104     WARNF("Unable to load stats file '%s'", fn);
105     return;
106 
107   }
108 
109   while ((lptr = fgets(buf, MAX_LINE, f))) {
110 
111     lineno++;
112     u8 *lstartptr = lptr;
113     u8 *rptr = lptr + strlen(lptr) - 1;
114     u8  keystring[MAX_LINE];
115     while (*lptr != ':' && lptr < rptr) {
116 
117       lptr++;
118 
119     }
120 
121     if (*lptr == '\n' || !*lptr) {
122 
123       WARNF("Unable to read line %d of stats file", lineno);
124       continue;
125 
126     }
127 
128     if (*lptr == ':') {
129 
130       *lptr = 0;
131       strcpy(keystring, lstartptr);
132       lptr++;
133       char *nptr;
134       switch (lineno) {
135 
136         case 3:
137           if (!strcmp(keystring, "run_time          "))
138             afl->prev_run_time = 1000 * strtoull(lptr, &nptr, 10);
139           break;
140         case 5:
141           if (!strcmp(keystring, "cycles_done       "))
142             afl->queue_cycle =
143                 strtoull(lptr, &nptr, 10) ? strtoull(lptr, &nptr, 10) + 1 : 0;
144           break;
145         case 7:
146           if (!strcmp(keystring, "execs_done        "))
147             afl->fsrv.total_execs = strtoull(lptr, &nptr, 10);
148           break;
149         case 10:
150           if (!strcmp(keystring, "corpus_count      ")) {
151 
152             u32 corpus_count = strtoul(lptr, &nptr, 10);
153             if (corpus_count != afl->queued_items) {
154 
155               WARNF(
156                   "queue/ has been modified -- things might not work, you're "
157                   "on your own!");
158 
159             }
160 
161           }
162 
163           break;
164         case 12:
165           if (!strcmp(keystring, "corpus_found      "))
166             afl->queued_discovered = strtoul(lptr, &nptr, 10);
167           break;
168         case 13:
169           if (!strcmp(keystring, "corpus_imported   "))
170             afl->queued_imported = strtoul(lptr, &nptr, 10);
171           break;
172         case 14:
173           if (!strcmp(keystring, "max_depth         "))
174             afl->max_depth = strtoul(lptr, &nptr, 10);
175           break;
176         case 21:
177           if (!strcmp(keystring, "saved_crashes    "))
178             afl->saved_crashes = strtoull(lptr, &nptr, 10);
179           break;
180         case 22:
181           if (!strcmp(keystring, "saved_hangs      "))
182             afl->saved_hangs = strtoull(lptr, &nptr, 10);
183           break;
184         default:
185           break;
186 
187       }
188 
189     }
190 
191   }
192 
193   if (afl->saved_crashes) { write_crash_readme(afl); }
194 
195   return;
196 
197 }
198 
199 /* Update stats file for unattended monitoring. */
200 
201 void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
202                       double stability, double eps) {
203 
204 #ifndef __HAIKU__
205   struct rusage rus;
206 #endif
207 
208   u64   cur_time = get_cur_time();
209   u8    fn[PATH_MAX];
210   FILE *f;
211 
212   snprintf(fn, PATH_MAX, "%s/fuzzer_stats", afl->out_dir);
213   f = create_ffile(fn);
214 
215   /* Keep last values in case we're called from another context
216      where exec/sec stats and such are not readily available. */
217 
218   if (!bitmap_cvg && !stability && !eps) {
219 
220     bitmap_cvg = afl->last_bitmap_cvg;
221     stability = afl->last_stability;
222 
223   } else {
224 
225     afl->last_bitmap_cvg = bitmap_cvg;
226     afl->last_stability = stability;
227     afl->last_eps = eps;
228 
229   }
230 
231   if ((unlikely(!afl->last_avg_exec_update ||
232                 cur_time - afl->last_avg_exec_update >= 60000))) {
233 
234     afl->last_avg_execs_saved =
235         (double)(1000 * (afl->fsrv.total_execs - afl->last_avg_execs)) /
236         (double)(cur_time - afl->last_avg_exec_update);
237     afl->last_avg_execs = afl->fsrv.total_execs;
238     afl->last_avg_exec_update = cur_time;
239 
240   }
241 
242 #ifndef __HAIKU__
243   if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
244 #endif
245 
246   fprintf(
247       f,
248       "start_time        : %llu\n"
249       "last_update       : %llu\n"
250       "run_time          : %llu\n"
251       "fuzzer_pid        : %u\n"
252       "cycles_done       : %llu\n"
253       "cycles_wo_finds   : %llu\n"
254       "execs_done        : %llu\n"
255       "execs_per_sec     : %0.02f\n"
256       "execs_ps_last_min : %0.02f\n"
257       "corpus_count      : %u\n"
258       "corpus_favored    : %u\n"
259       "corpus_found      : %u\n"
260       "corpus_imported   : %u\n"
261       "corpus_variable   : %u\n"
262       "max_depth         : %u\n"
263       "cur_item          : %u\n"
264       "pending_favs      : %u\n"
265       "pending_total     : %u\n"
266       "stability         : %0.02f%%\n"
267       "bitmap_cvg        : %0.02f%%\n"
268       "saved_crashes     : %llu\n"
269       "saved_hangs       : %llu\n"
270       "last_find         : %llu\n"
271       "last_crash        : %llu\n"
272       "last_hang         : %llu\n"
273       "execs_since_crash : %llu\n"
274       "exec_timeout      : %u\n"
275       "slowest_exec_ms   : %u\n"
276       "peak_rss_mb       : %lu\n"
277       "cpu_affinity      : %d\n"
278       "edges_found       : %u\n"
279       "total_edges       : %u\n"
280       "var_byte_count    : %u\n"
281       "havoc_expansion   : %u\n"
282       "auto_dict_entries : %u\n"
283       "testcache_size    : %llu\n"
284       "testcache_count   : %u\n"
285       "testcache_evict   : %u\n"
286       "afl_banner        : %s\n"
287       "afl_version       : " VERSION
288       "\n"
289       "target_mode       : %s%s%s%s%s%s%s%s%s%s\n"
290       "command_line      : %s\n",
291       (afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000,
292       (afl->prev_run_time + cur_time - afl->start_time) / 1000, (u32)getpid(),
293       afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds,
294       afl->fsrv.total_execs,
295       afl->fsrv.total_execs /
296           ((double)(afl->prev_run_time + get_cur_time() - afl->start_time) /
297            1000),
298       afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored,
299       afl->queued_discovered, afl->queued_imported, afl->queued_variable,
300       afl->max_depth, afl->current_entry, afl->pending_favored,
301       afl->pending_not_fuzzed, stability, bitmap_cvg, afl->saved_crashes,
302       afl->saved_hangs, afl->last_find_time / 1000, afl->last_crash_time / 1000,
303       afl->last_hang_time / 1000, afl->fsrv.total_execs - afl->last_crash_execs,
304       afl->fsrv.exec_tmout, afl->slowest_exec_ms,
305 #ifndef __HAIKU__
306   #ifdef __APPLE__
307       (unsigned long int)(rus.ru_maxrss >> 20),
308   #else
309       (unsigned long int)(rus.ru_maxrss >> 10),
310   #endif
311 #else
312       -1UL,
313 #endif
314 #ifdef HAVE_AFFINITY
315       afl->cpu_aff,
316 #else
317       -1,
318 #endif
319       t_bytes, afl->fsrv.real_map_size, afl->var_byte_count, afl->expand_havoc,
320       afl->a_extras_cnt, afl->q_testcase_cache_size,
321       afl->q_testcase_cache_count, afl->q_testcase_evictions, afl->use_banner,
322       afl->unicorn_mode ? "unicorn" : "", afl->fsrv.qemu_mode ? "qemu " : "",
323       afl->fsrv.cs_mode ? "coresight" : "",
324       afl->non_instrumented_mode ? " non_instrumented " : "",
325       afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",
326       afl->persistent_mode ? "persistent " : "",
327       afl->shmem_testcase_mode ? "shmem_testcase " : "",
328       afl->deferred_mode ? "deferred " : "",
329       (afl->unicorn_mode || afl->fsrv.qemu_mode || afl->fsrv.cs_mode ||
330        afl->non_instrumented_mode || afl->no_forkserver || afl->crash_mode ||
331        afl->persistent_mode || afl->deferred_mode)
332           ? ""
333           : "default",
334       afl->orig_cmdline);
335 
336   /* ignore errors */
337 
338   if (afl->debug) {
339 
340     u32 i = 0;
341     fprintf(f, "virgin_bytes     :");
342     for (i = 0; i < afl->fsrv.real_map_size; i++) {
343 
344       if (afl->virgin_bits[i] != 0xff) {
345 
346         fprintf(f, " %u[%02x]", i, afl->virgin_bits[i]);
347 
348       }
349 
350     }
351 
352     fprintf(f, "\n");
353     fprintf(f, "var_bytes        :");
354     for (i = 0; i < afl->fsrv.real_map_size; i++) {
355 
356       if (afl->var_bytes[i]) { fprintf(f, " %u", i); }
357 
358     }
359 
360     fprintf(f, "\n");
361 
362   }
363 
364   fclose(f);
365 
366 }
367 
368 /* Update the plot file if there is a reason to. */
369 
370 void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
371                             double eps) {
372 
373   if (unlikely(!afl->force_ui_update &&
374                (afl->stop_soon ||
375                 (afl->plot_prev_qp == afl->queued_items &&
376                  afl->plot_prev_pf == afl->pending_favored &&
377                  afl->plot_prev_pnf == afl->pending_not_fuzzed &&
378                  afl->plot_prev_ce == afl->current_entry &&
379                  afl->plot_prev_qc == afl->queue_cycle &&
380                  afl->plot_prev_uc == afl->saved_crashes &&
381                  afl->plot_prev_uh == afl->saved_hangs &&
382                  afl->plot_prev_md == afl->max_depth &&
383                  afl->plot_prev_ed == afl->fsrv.total_execs) ||
384                 !afl->queue_cycle ||
385                 get_cur_time() - afl->start_time <= 60000))) {
386 
387     return;
388 
389   }
390 
391   afl->plot_prev_qp = afl->queued_items;
392   afl->plot_prev_pf = afl->pending_favored;
393   afl->plot_prev_pnf = afl->pending_not_fuzzed;
394   afl->plot_prev_ce = afl->current_entry;
395   afl->plot_prev_qc = afl->queue_cycle;
396   afl->plot_prev_uc = afl->saved_crashes;
397   afl->plot_prev_uh = afl->saved_hangs;
398   afl->plot_prev_md = afl->max_depth;
399   afl->plot_prev_ed = afl->fsrv.total_execs;
400 
401   /* Fields in the file:
402 
403      relative_time, afl->cycles_done, cur_item, corpus_count, corpus_not_fuzzed,
404      favored_not_fuzzed, saved_crashes, saved_hangs, max_depth,
405      execs_per_sec, edges_found */
406 
407   fprintf(afl->fsrv.plot_file,
408           "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, "
409           "%u\n",
410           ((afl->prev_run_time + get_cur_time() - afl->start_time) / 1000),
411           afl->queue_cycle - 1, afl->current_entry, afl->queued_items,
412           afl->pending_not_fuzzed, afl->pending_favored, bitmap_cvg,
413           afl->saved_crashes, afl->saved_hangs, afl->max_depth, eps,
414           afl->plot_prev_ed, t_bytes);                     /* ignore errors */
415 
416   fflush(afl->fsrv.plot_file);
417 
418 }
419 
420 /* Check terminal dimensions after resize. */
421 
422 static void check_term_size(afl_state_t *afl) {
423 
424   struct winsize ws;
425 
426   afl->term_too_small = 0;
427 
428   if (ioctl(1, TIOCGWINSZ, &ws)) { return; }
429 
430   if (ws.ws_row == 0 || ws.ws_col == 0) { return; }
431   if (ws.ws_row < 24 || ws.ws_col < 79) { afl->term_too_small = 1; }
432 
433 }
434 
435 /* A spiffy retro stats screen! This is called every afl->stats_update_freq
436    execve() calls, plus in several other circumstances. */
437 
438 void show_stats(afl_state_t *afl) {
439 
440   if (afl->pizza_is_served) {
441 
442     show_stats_pizza(afl);
443 
444   } else {
445 
446     show_stats_normal(afl);
447 
448   }
449 
450 }
451 
452 void show_stats_normal(afl_state_t *afl) {
453 
454   double t_byte_ratio, stab_ratio;
455 
456   u64 cur_ms;
457   u32 t_bytes, t_bits;
458 
459   static u8 banner[128];
460   u32       banner_len, banner_pad;
461   u8        tmp[256];
462   u8        time_tmp[64];
463 
464   u8 val_buf[8][STRINGIFY_VAL_SIZE_MAX];
465 #define IB(i) (val_buf[(i)])
466 
467   cur_ms = get_cur_time();
468 
469   if (afl->most_time_key) {
470 
471     if (afl->most_time * 1000 < cur_ms - afl->start_time) {
472 
473       afl->most_time_key = 2;
474       afl->stop_soon = 2;
475 
476     }
477 
478   }
479 
480   if (afl->most_execs_key == 1) {
481 
482     if (afl->most_execs <= afl->fsrv.total_execs) {
483 
484       afl->most_execs_key = 2;
485       afl->stop_soon = 2;
486 
487     }
488 
489   }
490 
491   /* If not enough time has passed since last UI update, bail out. */
492 
493   if (cur_ms - afl->stats_last_ms < 1000 / UI_TARGET_HZ &&
494       !afl->force_ui_update) {
495 
496     return;
497 
498   }
499 
500   /* Check if we're past the 10 minute mark. */
501 
502   if (cur_ms - afl->start_time > 10 * 60 * 1000) { afl->run_over10m = 1; }
503 
504   /* Calculate smoothed exec speed stats. */
505 
506   if (unlikely(!afl->stats_last_execs)) {
507 
508     if (likely(cur_ms != afl->start_time)) {
509 
510       afl->stats_avg_exec = ((double)afl->fsrv.total_execs) * 1000 /
511                             (afl->prev_run_time + cur_ms - afl->start_time);
512 
513     }
514 
515   } else {
516 
517     if (likely(cur_ms != afl->stats_last_ms)) {
518 
519       double cur_avg =
520           ((double)(afl->fsrv.total_execs - afl->stats_last_execs)) * 1000 /
521           (cur_ms - afl->stats_last_ms);
522 
523       /* If there is a dramatic (5x+) jump in speed, reset the indicator
524          more quickly. */
525 
526       if (cur_avg * 5 < afl->stats_avg_exec ||
527           cur_avg / 5 > afl->stats_avg_exec) {
528 
529         afl->stats_avg_exec = cur_avg;
530 
531       }
532 
533       afl->stats_avg_exec = afl->stats_avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) +
534                             cur_avg * (1.0 / AVG_SMOOTHING);
535 
536     }
537 
538   }
539 
540   afl->stats_last_ms = cur_ms;
541   afl->stats_last_execs = afl->fsrv.total_execs;
542 
543   /* Tell the callers when to contact us (as measured in execs). */
544 
545   afl->stats_update_freq = afl->stats_avg_exec / (UI_TARGET_HZ * 10);
546   if (!afl->stats_update_freq) { afl->stats_update_freq = 1; }
547 
548   /* Do some bitmap stats. */
549 
550   t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
551   t_byte_ratio = ((double)t_bytes * 100) / afl->fsrv.real_map_size;
552 
553   if (unlikely(t_bytes > afl->fsrv.real_map_size)) {
554 
555     if (unlikely(!afl->afl_env.afl_ignore_problems)) {
556 
557       FATAL(
558           "Incorrect fuzzing setup detected. Your target seems to have loaded "
559           "incorrectly instrumented shared libraries (%u of %u/%u). If you use "
560           "LTO mode "
561           "please see instrumentation/README.lto.md. To ignore this problem "
562           "and continue fuzzing just set 'AFL_IGNORE_PROBLEMS=1'.\n",
563           t_bytes, afl->fsrv.real_map_size, afl->fsrv.map_size);
564 
565     }
566 
567   }
568 
569   if (likely(t_bytes) && unlikely(afl->var_byte_count)) {
570 
571     stab_ratio = 100 - (((double)afl->var_byte_count * 100) / t_bytes);
572 
573   } else {
574 
575     stab_ratio = 100;
576 
577   }
578 
579   /* Roughly every minute, update fuzzer stats and save auto tokens. */
580 
581   if (unlikely(!afl->non_instrumented_mode &&
582                (afl->force_ui_update ||
583                 cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000))) {
584 
585     afl->stats_last_stats_ms = cur_ms;
586     write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio,
587                      afl->stats_avg_exec);
588     save_auto(afl);
589     write_bitmap(afl);
590 
591   }
592 
593   if (unlikely(afl->afl_env.afl_statsd)) {
594 
595     if (unlikely(afl->force_ui_update || cur_ms - afl->statsd_last_send_ms >
596                                              STATSD_UPDATE_SEC * 1000)) {
597 
598       /* reset counter, even if send failed. */
599       afl->statsd_last_send_ms = cur_ms;
600       if (statsd_send_metric(afl)) { WARNF("could not send statsd metric."); }
601 
602     }
603 
604   }
605 
606   /* Every now and then, write plot data. */
607 
608   if (unlikely(afl->force_ui_update ||
609                cur_ms - afl->stats_last_plot_ms > PLOT_UPDATE_SEC * 1000)) {
610 
611     afl->stats_last_plot_ms = cur_ms;
612     maybe_update_plot_file(afl, t_bytes, t_byte_ratio, afl->stats_avg_exec);
613 
614   }
615 
616   /* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
617 
618   if (unlikely(!afl->non_instrumented_mode && afl->cycles_wo_finds > 100 &&
619                !afl->pending_not_fuzzed && afl->afl_env.afl_exit_when_done)) {
620 
621     afl->stop_soon = 2;
622 
623   }
624 
625   /* AFL_EXIT_ON_TIME. */
626 
627   if (unlikely(afl->last_find_time && !afl->non_instrumented_mode &&
628                afl->afl_env.afl_exit_on_time &&
629                (cur_ms - afl->last_find_time) > afl->exit_on_time)) {
630 
631     afl->stop_soon = 2;
632 
633   }
634 
635   if (unlikely(afl->total_crashes && afl->afl_env.afl_bench_until_crash)) {
636 
637     afl->stop_soon = 2;
638 
639   }
640 
641   /* If we're not on TTY, bail out. */
642 
643   if (afl->not_on_tty) { return; }
644 
645   /* If we haven't started doing things, bail out. */
646 
647   if (unlikely(!afl->queue_cur)) { return; }
648 
649   /* Compute some mildly useful bitmap stats. */
650 
651   t_bits = (afl->fsrv.map_size << 3) - count_bits(afl, afl->virgin_bits);
652 
653   /* Now, for the visuals... */
654 
655   if (afl->clear_screen) {
656 
657     SAYF(TERM_CLEAR CURSOR_HIDE);
658     afl->clear_screen = 0;
659 
660     check_term_size(afl);
661 
662   }
663 
664   SAYF(TERM_HOME);
665 
666   if (unlikely(afl->term_too_small)) {
667 
668     SAYF(cBRI
669          "Your terminal is too small to display the UI.\n"
670          "Please resize terminal window to at least 79x24.\n" cRST);
671 
672     return;
673 
674   }
675 
676   /* Let's start by drawing a centered banner. */
677   if (unlikely(!banner[0])) {
678 
679     char *si = "";
680     if (afl->sync_id) { si = afl->sync_id; }
681     memset(banner, 0, sizeof(banner));
682     banner_len = (afl->crash_mode ? 20 : 18) + strlen(VERSION) + strlen(si) +
683                  strlen(afl->power_name) + 4 + 6;
684 
685     if (strlen(afl->use_banner) + banner_len > 75) {
686 
687       afl->use_banner += (strlen(afl->use_banner) + banner_len) - 76;
688       memset(afl->use_banner, '.', 3);
689 
690     }
691 
692     banner_len += strlen(afl->use_banner);
693     banner_pad = (79 - banner_len) / 2;
694     memset(banner, ' ', banner_pad);
695 
696 #ifdef __linux__
697     if (afl->fsrv.nyx_mode) {
698 
699       sprintf(banner + banner_pad,
700               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
701               afl->crash_mode ? cPIN "peruvian were-rabbit"
702                               : cYEL "american fuzzy lop",
703               si, afl->use_banner, afl->power_name);
704 
705     } else {
706 
707 #endif
708       sprintf(banner + banner_pad,
709               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
710               afl->crash_mode ? cPIN "peruvian were-rabbit"
711                               : cYEL "american fuzzy lop",
712               si, afl->use_banner, afl->power_name);
713 
714 #ifdef __linux__
715 
716     }
717 
718 #endif
719 
720   }
721 
722   SAYF("\n%s\n", banner);
723 
724   /* "Handy" shortcuts for drawing boxes... */
725 
726 #define bSTG bSTART cGRA
727 #define bH2 bH bH
728 #define bH5 bH2 bH2 bH
729 #define bH10 bH5 bH5
730 #define bH20 bH10 bH10
731 #define bH30 bH20 bH10
732 #define SP5 "     "
733 #define SP10 SP5 SP5
734 #define SP20 SP10 SP10
735 
736   /* Since `total_crashes` does not get reloaded from disk on restart,
737     it indicates if we found crashes this round already -> paint red.
738     If it's 0, but `saved_crashes` is set from a past run, paint in yellow. */
739   char *crash_color = afl->total_crashes   ? cLRD
740                       : afl->saved_crashes ? cYEL
741                                            : cRST;
742 
743   /* Lord, forgive me this. */
744 
745   SAYF(SET_G1 bSTG bLT bH bSTOP                         cCYA
746        " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
747        " overall results " bSTG bH2 bH2                 bRT "\n");
748 
749   if (afl->non_instrumented_mode) {
750 
751     strcpy(tmp, cRST);
752 
753   } else {
754 
755     u64 min_wo_finds = (cur_ms - afl->last_find_time) / 1000 / 60;
756 
757     /* First queue cycle: don't stop now! */
758     if (afl->queue_cycle == 1 || min_wo_finds < 15) {
759 
760       strcpy(tmp, cMGN);
761 
762     } else
763 
764         /* Subsequent cycles, but we're still making finds. */
765         if (afl->cycles_wo_finds < 25 || min_wo_finds < 30) {
766 
767       strcpy(tmp, cYEL);
768 
769     } else
770 
771         /* No finds for a long time and no test cases to try. */
772         if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed &&
773             min_wo_finds > 120) {
774 
775       strcpy(tmp, cLGN);
776 
777       /* Default: cautiously OK to stop? */
778 
779     } else {
780 
781       strcpy(tmp, cLBL);
782 
783     }
784 
785   }
786 
787   u_stringify_time_diff(time_tmp, afl->prev_run_time + cur_ms, afl->start_time);
788   SAYF(bV bSTOP "        run time : " cRST "%-33s " bSTG bV bSTOP
789                 "  cycles done : %s%-5s " bSTG              bV "\n",
790        time_tmp, tmp, u_stringify_int(IB(0), afl->queue_cycle - 1));
791 
792   /* We want to warn people about not seeing new paths after a full cycle,
793      except when resuming fuzzing or running in non-instrumented mode. */
794 
795   if (!afl->non_instrumented_mode &&
796       (afl->last_find_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
797        afl->in_bitmap || afl->crash_mode)) {
798 
799     u_stringify_time_diff(time_tmp, cur_ms, afl->last_find_time);
800     SAYF(bV bSTOP "   last new find : " cRST "%-33s ", time_tmp);
801 
802   } else {
803 
804     if (afl->non_instrumented_mode) {
805 
806       SAYF(bV bSTOP "   last new find : " cPIN "n/a" cRST
807                     " (non-instrumented mode)       ");
808 
809     } else {
810 
811       SAYF(bV bSTOP "   last new find : " cRST "none yet " cLRD
812                     "(odd, check syntax!)     ");
813 
814     }
815 
816   }
817 
818   SAYF(bSTG bV bSTOP " corpus count : " cRST "%-5s " bSTG bV "\n",
819        u_stringify_int(IB(0), afl->queued_items));
820 
821   /* Highlight crashes in red if found, denote going over the KEEP_UNIQUE_CRASH
822      limit with a '+' appended to the count. */
823 
824   sprintf(tmp, "%s%s", u_stringify_int(IB(0), afl->saved_crashes),
825           (afl->saved_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
826 
827   u_stringify_time_diff(time_tmp, cur_ms, afl->last_crash_time);
828   SAYF(bV bSTOP "last saved crash : " cRST "%-33s " bSTG bV bSTOP
829                 "saved crashes : %s%-6s" bSTG               bV "\n",
830        time_tmp, crash_color, tmp);
831 
832   sprintf(tmp, "%s%s", u_stringify_int(IB(0), afl->saved_hangs),
833           (afl->saved_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
834 
835   u_stringify_time_diff(time_tmp, cur_ms, afl->last_hang_time);
836   SAYF(bV bSTOP " last saved hang : " cRST "%-33s " bSTG bV bSTOP
837                 "  saved hangs : " cRST "%-6s" bSTG         bV "\n",
838        time_tmp, tmp);
839 
840   SAYF(bVR bH bSTOP                                              cCYA
841        " cycle progress " bSTG bH10 bH5 bH2 bH2 bH2 bHB bH bSTOP cCYA
842        " map coverage" bSTG bHT bH20 bH2                         bVL "\n");
843 
844   /* This gets funny because we want to print several variable-length variables
845      together, but then cram them into a fixed-width field - so we need to
846      put them in a temporary buffer first. */
847 
848   sprintf(tmp, "%s%s%u (%0.01f%%)", u_stringify_int(IB(0), afl->current_entry),
849           afl->queue_cur->favored ? "." : "*", afl->queue_cur->fuzz_level,
850           ((double)afl->current_entry * 100) / afl->queued_items);
851 
852   SAYF(bV bSTOP "  now processing : " cRST "%-18s " bSTG bV bSTOP, tmp);
853 
854   sprintf(tmp, "%0.02f%% / %0.02f%%",
855           ((double)afl->queue_cur->bitmap_size) * 100 / afl->fsrv.real_map_size,
856           t_byte_ratio);
857 
858   SAYF("    map density : %s%-19s" bSTG bV "\n",
859        t_byte_ratio > 70
860            ? cLRD
861            : ((t_bytes < 200 && !afl->non_instrumented_mode) ? cPIN : cRST),
862        tmp);
863 
864   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_items),
865           ((double)afl->cur_skipped_items * 100) / afl->queued_items);
866 
867   SAYF(bV bSTOP "  runs timed out : " cRST "%-18s " bSTG bV, tmp);
868 
869   sprintf(tmp, "%0.02f bits/tuple", t_bytes ? (((double)t_bits) / t_bytes) : 0);
870 
871   SAYF(bSTOP " count coverage : " cRST "%-19s" bSTG bV "\n", tmp);
872 
873   SAYF(bVR bH bSTOP                                             cCYA
874        " stage progress " bSTG bH10 bH5 bH2 bH2 bH2 bX bH bSTOP cCYA
875        " findings in depth " bSTG bH10 bH5 bH2                  bVL "\n");
876 
877   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
878           ((double)afl->queued_favored) * 100 / afl->queued_items);
879 
880   /* Yeah... it's still going on... halp? */
881 
882   SAYF(bV bSTOP "  now trying : " cRST "%-22s " bSTG bV bSTOP
883                 " favored items : " cRST "%-20s" bSTG   bV "\n",
884        afl->stage_name, tmp);
885 
886   if (!afl->stage_max) {
887 
888     sprintf(tmp, "%s/-", u_stringify_int(IB(0), afl->stage_cur));
889 
890   } else {
891 
892     sprintf(tmp, "%s/%s (%0.02f%%)", u_stringify_int(IB(0), afl->stage_cur),
893             u_stringify_int(IB(1), afl->stage_max),
894             ((double)afl->stage_cur) * 100 / afl->stage_max);
895 
896   }
897 
898   SAYF(bV bSTOP " stage execs : " cRST "%-23s" bSTG bV bSTOP, tmp);
899 
900   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_with_cov),
901           ((double)afl->queued_with_cov) * 100 / afl->queued_items);
902 
903   SAYF("  new edges on : " cRST "%-20s" bSTG bV "\n", tmp);
904 
905   sprintf(tmp, "%s (%s%s saved)", u_stringify_int(IB(0), afl->total_crashes),
906           u_stringify_int(IB(1), afl->saved_crashes),
907           (afl->saved_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
908 
909   if (afl->crash_mode) {
910 
911     SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP
912                   "   new crashes : %s%-20s" bSTG         bV "\n",
913          u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
914 
915   } else {
916 
917     SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP
918                   " total crashes : %s%-20s" bSTG         bV "\n",
919          u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
920 
921   }
922 
923   /* Show a warning about slow execution. */
924 
925   if (afl->stats_avg_exec < 100) {
926 
927     sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec),
928             afl->stats_avg_exec < 20 ? "zzzz..." : "slow!");
929 
930     SAYF(bV bSTOP "  exec speed : " cLRD "%-22s ", tmp);
931 
932   } else {
933 
934     sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec));
935     SAYF(bV bSTOP "  exec speed : " cRST "%-22s ", tmp);
936 
937   }
938 
939   sprintf(tmp, "%s (%s%s saved)", u_stringify_int(IB(0), afl->total_tmouts),
940           u_stringify_int(IB(1), afl->saved_tmouts),
941           (afl->saved_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
942 
943   SAYF(bSTG bV bSTOP "  total tmouts : " cRST "%-20s" bSTG bV "\n", tmp);
944 
945   /* Aaaalmost there... hold on! */
946 
947   SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bH2 bHT bH10 bH2
948            bH bHB bH bSTOP cCYA " item geometry " bSTG bH5 bH2 bVL "\n");
949 
950   if (unlikely(afl->custom_only)) {
951 
952     strcpy(tmp, "disabled (custom-mutator-only mode)");
953 
954   } else if (likely(afl->skip_deterministic)) {
955 
956     strcpy(tmp, "disabled (default, enable with -D)");
957 
958   } else {
959 
960     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
961             u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]),
962             u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]),
963             u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]),
964             u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]),
965             u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP4]),
966             u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4]));
967 
968   }
969 
970   SAYF(bV bSTOP "   bit flips : " cRST "%-36s " bSTG bV bSTOP
971                 "    levels : " cRST "%-10s" bSTG       bV "\n",
972        tmp, u_stringify_int(IB(0), afl->max_depth));
973 
974   if (unlikely(!afl->skip_deterministic)) {
975 
976     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
977             u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]),
978             u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]),
979             u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]),
980             u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]),
981             u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]),
982             u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32]));
983 
984   }
985 
986   SAYF(bV bSTOP "  byte flips : " cRST "%-36s " bSTG bV bSTOP
987                 "   pending : " cRST "%-10s" bSTG       bV "\n",
988        tmp, u_stringify_int(IB(0), afl->pending_not_fuzzed));
989 
990   if (unlikely(!afl->skip_deterministic)) {
991 
992     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
993             u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]),
994             u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]),
995             u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]),
996             u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]),
997             u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]),
998             u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32]));
999 
1000   }
1001 
1002   SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP
1003                 "  pend fav : " cRST "%-10s" bSTG       bV "\n",
1004        tmp, u_stringify_int(IB(0), afl->pending_favored));
1005 
1006   if (unlikely(!afl->skip_deterministic)) {
1007 
1008     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
1009             u_stringify_int(IB(0), afl->stage_finds[STAGE_INTEREST8]),
1010             u_stringify_int(IB(1), afl->stage_cycles[STAGE_INTEREST8]),
1011             u_stringify_int(IB(2), afl->stage_finds[STAGE_INTEREST16]),
1012             u_stringify_int(IB(3), afl->stage_cycles[STAGE_INTEREST16]),
1013             u_stringify_int(IB(4), afl->stage_finds[STAGE_INTEREST32]),
1014             u_stringify_int(IB(5), afl->stage_cycles[STAGE_INTEREST32]));
1015 
1016   }
1017 
1018   SAYF(bV bSTOP "  known ints : " cRST "%-36s " bSTG bV bSTOP
1019                 " own finds : " cRST "%-10s" bSTG       bV "\n",
1020        tmp, u_stringify_int(IB(0), afl->queued_discovered));
1021 
1022   if (unlikely(!afl->skip_deterministic)) {
1023 
1024     sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
1025             u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
1026             u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
1027             u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]),
1028             u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]),
1029             u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
1030             u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]),
1031             u_stringify_int(IB(6), afl->stage_finds[STAGE_EXTRAS_AI]),
1032             u_stringify_int(IB(7), afl->stage_cycles[STAGE_EXTRAS_AI]));
1033 
1034   } else if (unlikely(!afl->extras_cnt || afl->custom_only)) {
1035 
1036     strcpy(tmp, "n/a");
1037 
1038   } else {
1039 
1040     strcpy(tmp, "havoc mode");
1041 
1042   }
1043 
1044   SAYF(bV bSTOP "  dictionary : " cRST "%-36s " bSTG bV bSTOP
1045                 "  imported : " cRST "%-10s" bSTG       bV "\n",
1046        tmp,
1047        afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported)
1048                     : (u8 *)"n/a");
1049 
1050   sprintf(tmp, "%s/%s, %s/%s",
1051           u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
1052           u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
1053           u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
1054           u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]));
1055 
1056   SAYF(bV bSTOP "havoc/splice : " cRST "%-36s " bSTG bV bSTOP, tmp);
1057 
1058   if (t_bytes) {
1059 
1060     sprintf(tmp, "%0.02f%%", stab_ratio);
1061 
1062   } else {
1063 
1064     strcpy(tmp, "n/a");
1065 
1066   }
1067 
1068   SAYF(" stability : %s%-10s" bSTG bV "\n",
1069        (stab_ratio < 85 && afl->var_byte_count > 40)
1070            ? cLRD
1071            : ((afl->queued_variable &&
1072                (!afl->persistent_mode || afl->var_byte_count > 20))
1073                   ? cMGN
1074                   : cRST),
1075        tmp);
1076 
1077   if (unlikely(afl->afl_env.afl_python_module)) {
1078 
1079     sprintf(tmp, "%s/%s,",
1080             u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
1081             u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]));
1082 
1083   } else {
1084 
1085     strcpy(tmp, "unused,");
1086 
1087   }
1088 
1089   if (unlikely(afl->afl_env.afl_custom_mutator_library)) {
1090 
1091     strcat(tmp, " ");
1092     strcat(tmp, u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]));
1093     strcat(tmp, "/");
1094     strcat(tmp,
1095            u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
1096     strcat(tmp, ",");
1097 
1098   } else {
1099 
1100     strcat(tmp, " unused,");
1101 
1102   }
1103 
1104   if (unlikely(afl->shm.cmplog_mode)) {
1105 
1106     strcat(tmp, " ");
1107     strcat(tmp, u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]));
1108     strcat(tmp, "/");
1109     strcat(tmp, u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]));
1110     strcat(tmp, ", ");
1111     strcat(tmp, u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]));
1112     strcat(tmp, "/");
1113     strcat(tmp, u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS]));
1114 
1115   } else {
1116 
1117     strcat(tmp, " unused, unused");
1118 
1119   }
1120 
1121   SAYF(bV bSTOP "py/custom/rq : " cRST "%-36s " bSTG bVR bH20 bH2 bH bRB "\n",
1122        tmp);
1123 
1124   if (likely(afl->disable_trim)) {
1125 
1126     sprintf(tmp, "disabled, ");
1127 
1128   } else if (unlikely(!afl->bytes_trim_out)) {
1129 
1130     sprintf(tmp, "n/a, ");
1131 
1132   } else {
1133 
1134     sprintf(tmp, "%0.02f%%/%s, ",
1135             ((double)(afl->bytes_trim_in - afl->bytes_trim_out)) * 100 /
1136                 afl->bytes_trim_in,
1137             u_stringify_int(IB(0), afl->trim_execs));
1138 
1139   }
1140 
1141   if (likely(afl->skip_deterministic)) {
1142 
1143     strcat(tmp, "disabled");
1144 
1145   } else if (unlikely(!afl->blocks_eff_total)) {
1146 
1147     strcat(tmp, "n/a");
1148 
1149   } else {
1150 
1151     u8 tmp2[128];
1152 
1153     sprintf(tmp2, "%0.02f%%",
1154             ((double)(afl->blocks_eff_total - afl->blocks_eff_select)) * 100 /
1155                 afl->blocks_eff_total);
1156 
1157     strcat(tmp, tmp2);
1158 
1159   }
1160 
1161   // if (afl->custom_mutators_count) {
1162 
1163   //
1164   //  sprintf(tmp, "%s/%s",
1165   //          u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
1166   //          u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
1167   //  SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
1168   //
1169   //} else {
1170 
1171   SAYF(bV bSTOP "    trim/eff : " cRST "%-36s " bSTG bV RESET_G1, tmp);
1172 
1173   //}
1174 
1175   /* Provide some CPU utilization stats. */
1176 
1177   if (afl->cpu_core_count) {
1178 
1179     char *spacing = SP10, snap[24] = " " cLGN "snapshot" cRST " ";
1180 
1181     double cur_runnable = get_runnable_processes();
1182     u32    cur_utilization = cur_runnable * 100 / afl->cpu_core_count;
1183 
1184     u8 *cpu_color = cCYA;
1185 
1186     /* If we could still run one or more processes, use green. */
1187 
1188     if (afl->cpu_core_count > 1 && cur_runnable + 1 <= afl->cpu_core_count) {
1189 
1190       cpu_color = cLGN;
1191 
1192     }
1193 
1194     /* If we're clearly oversubscribed, use red. */
1195 
1196     if (!afl->no_cpu_meter_red && cur_utilization >= 150) { cpu_color = cLRD; }
1197 
1198     if (afl->fsrv.snapshot) { spacing = snap; }
1199 
1200 #ifdef HAVE_AFFINITY
1201 
1202     if (afl->cpu_aff >= 0) {
1203 
1204       SAYF("%s" cGRA "[cpu%03u:%s%3u%%" cGRA "]\r" cRST, spacing,
1205            MIN(afl->cpu_aff, 999), cpu_color, MIN(cur_utilization, (u32)999));
1206 
1207     } else {
1208 
1209       SAYF("%s" cGRA "   [cpu:%s%3u%%" cGRA "]\r" cRST, spacing, cpu_color,
1210            MIN(cur_utilization, (u32)999));
1211 
1212     }
1213 
1214 #else
1215 
1216     SAYF("%s" cGRA "   [cpu:%s%3u%%" cGRA "]\r" cRST, spacing, cpu_color,
1217          MIN(cur_utilization, (u32)999));
1218 
1219 #endif                                                    /* ^HAVE_AFFINITY */
1220 
1221   } else {
1222 
1223     SAYF("\r");
1224 
1225   }
1226 
1227   /* Last line */
1228   SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1);
1229 
1230 #undef IB
1231 
1232   /* Hallelujah! */
1233 
1234   fflush(0);
1235 
1236 }
1237 
1238 void show_stats_pizza(afl_state_t *afl) {
1239 
1240   double t_byte_ratio, stab_ratio;
1241 
1242   u64 cur_ms;
1243   u32 t_bytes, t_bits;
1244 
1245   static u8 banner[128];
1246   u32       banner_len, banner_pad;
1247   u8        tmp[256];
1248   u8        time_tmp[64];
1249 
1250   u8 val_buf[8][STRINGIFY_VAL_SIZE_MAX];
1251 #define IB(i) (val_buf[(i)])
1252 
1253   cur_ms = get_cur_time();
1254 
1255   if (afl->most_time_key) {
1256 
1257     if (afl->most_time * 1000 < cur_ms - afl->start_time) {
1258 
1259       afl->most_time_key = 2;
1260       afl->stop_soon = 2;
1261 
1262     }
1263 
1264   }
1265 
1266   if (afl->most_execs_key == 1) {
1267 
1268     if (afl->most_execs <= afl->fsrv.total_execs) {
1269 
1270       afl->most_execs_key = 2;
1271       afl->stop_soon = 2;
1272 
1273     }
1274 
1275   }
1276 
1277   /* If not enough time has passed since last UI update, bail out. */
1278 
1279   if (cur_ms - afl->stats_last_ms < 1000 / UI_TARGET_HZ &&
1280       !afl->force_ui_update) {
1281 
1282     return;
1283 
1284   }
1285 
1286   /* Check if we're past the 10 minute mark. */
1287 
1288   if (cur_ms - afl->start_time > 10 * 60 * 1000) { afl->run_over10m = 1; }
1289 
1290   /* Calculate smoothed exec speed stats. */
1291 
1292   if (unlikely(!afl->stats_last_execs)) {
1293 
1294     if (likely(cur_ms != afl->start_time)) {
1295 
1296       afl->stats_avg_exec = ((double)afl->fsrv.total_execs) * 1000 /
1297                             (afl->prev_run_time + cur_ms - afl->start_time);
1298 
1299     }
1300 
1301   } else {
1302 
1303     if (likely(cur_ms != afl->stats_last_ms)) {
1304 
1305       double cur_avg =
1306           ((double)(afl->fsrv.total_execs - afl->stats_last_execs)) * 1000 /
1307           (cur_ms - afl->stats_last_ms);
1308 
1309       /* If there is a dramatic (5x+) jump in speed, reset the indicator
1310          more quickly. */
1311 
1312       if (cur_avg * 5 < afl->stats_avg_exec ||
1313           cur_avg / 5 > afl->stats_avg_exec) {
1314 
1315         afl->stats_avg_exec = cur_avg;
1316 
1317       }
1318 
1319       afl->stats_avg_exec = afl->stats_avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) +
1320                             cur_avg * (1.0 / AVG_SMOOTHING);
1321 
1322     }
1323 
1324   }
1325 
1326   afl->stats_last_ms = cur_ms;
1327   afl->stats_last_execs = afl->fsrv.total_execs;
1328 
1329   /* Tell the callers when to contact us (as measured in execs). */
1330 
1331   afl->stats_update_freq = afl->stats_avg_exec / (UI_TARGET_HZ * 10);
1332   if (!afl->stats_update_freq) { afl->stats_update_freq = 1; }
1333 
1334   /* Do some bitmap stats. */
1335 
1336   t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
1337   t_byte_ratio = ((double)t_bytes * 100) / afl->fsrv.real_map_size;
1338 
1339   if (unlikely(t_bytes > afl->fsrv.real_map_size)) {
1340 
1341     if (unlikely(!afl->afl_env.afl_ignore_problems)) {
1342 
1343       FATAL(
1344           "This is what happens when you speak italian to the rabbit "
1345           "Don't speak italian to the rabbit");
1346 
1347     }
1348 
1349   }
1350 
1351   if (likely(t_bytes) && unlikely(afl->var_byte_count)) {
1352 
1353     stab_ratio = 100 - (((double)afl->var_byte_count * 100) / t_bytes);
1354 
1355   } else {
1356 
1357     stab_ratio = 100;
1358 
1359   }
1360 
1361   /* Roughly every minute, update fuzzer stats and save auto tokens. */
1362 
1363   if (unlikely(!afl->non_instrumented_mode &&
1364                (afl->force_ui_update ||
1365                 cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000))) {
1366 
1367     afl->stats_last_stats_ms = cur_ms;
1368     write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio,
1369                      afl->stats_avg_exec);
1370     save_auto(afl);
1371     write_bitmap(afl);
1372 
1373   }
1374 
1375   if (unlikely(afl->afl_env.afl_statsd)) {
1376 
1377     if (unlikely(afl->force_ui_update || cur_ms - afl->statsd_last_send_ms >
1378                                              STATSD_UPDATE_SEC * 1000)) {
1379 
1380       /* reset counter, even if send failed. */
1381       afl->statsd_last_send_ms = cur_ms;
1382       if (statsd_send_metric(afl)) {
1383 
1384         WARNF("Could not order tomato sauce from statsd.");
1385 
1386       }
1387 
1388     }
1389 
1390   }
1391 
1392   /* Every now and then, write plot data. */
1393 
1394   if (unlikely(afl->force_ui_update ||
1395                cur_ms - afl->stats_last_plot_ms > PLOT_UPDATE_SEC * 1000)) {
1396 
1397     afl->stats_last_plot_ms = cur_ms;
1398     maybe_update_plot_file(afl, t_bytes, t_byte_ratio, afl->stats_avg_exec);
1399 
1400   }
1401 
1402   /* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
1403 
1404   if (unlikely(!afl->non_instrumented_mode && afl->cycles_wo_finds > 100 &&
1405                !afl->pending_not_fuzzed && afl->afl_env.afl_exit_when_done)) {
1406 
1407     afl->stop_soon = 2;
1408 
1409   }
1410 
1411   /* AFL_EXIT_ON_TIME. */
1412 
1413   if (unlikely(afl->last_find_time && !afl->non_instrumented_mode &&
1414                afl->afl_env.afl_exit_on_time &&
1415                (cur_ms - afl->last_find_time) > afl->exit_on_time)) {
1416 
1417     afl->stop_soon = 2;
1418 
1419   }
1420 
1421   if (unlikely(afl->total_crashes && afl->afl_env.afl_bench_until_crash)) {
1422 
1423     afl->stop_soon = 2;
1424 
1425   }
1426 
1427   /* If we're not on TTY, bail out. */
1428 
1429   if (afl->not_on_tty) { return; }
1430 
1431   /* If we haven't started doing things, bail out. */
1432 
1433   if (unlikely(!afl->queue_cur)) { return; }
1434 
1435   /* Compute some mildly useful bitmap stats. */
1436 
1437   t_bits = (afl->fsrv.map_size << 3) - count_bits(afl, afl->virgin_bits);
1438 
1439   /* Now, for the visuals... */
1440 
1441   if (afl->clear_screen) {
1442 
1443     SAYF(TERM_CLEAR CURSOR_HIDE);
1444     afl->clear_screen = 0;
1445 
1446     check_term_size(afl);
1447 
1448   }
1449 
1450   SAYF(TERM_HOME);
1451 
1452   if (unlikely(afl->term_too_small)) {
1453 
1454     SAYF(cBRI
1455          "Our pizzeria can't host this many guests.\n"
1456          "Please call Pizzeria Caravaggio. They have tables of at least "
1457          "79x24.\n" cRST);
1458 
1459     return;
1460 
1461   }
1462 
1463   /* Let's start by drawing a centered banner. */
1464   if (unlikely(!banner[0])) {
1465 
1466     char *si = "";
1467     if (afl->sync_id) { si = afl->sync_id; }
1468     memset(banner, 0, sizeof(banner));
1469     banner_len = (afl->crash_mode ? 20 : 18) + strlen(VERSION) + strlen(si) +
1470                  strlen(afl->power_name) + 4 + 6;
1471 
1472     if (strlen(afl->use_banner) + banner_len > 75) {
1473 
1474       afl->use_banner += (strlen(afl->use_banner) + banner_len) - 76;
1475       memset(afl->use_banner, '.', 3);
1476 
1477     }
1478 
1479     banner_len += strlen(afl->use_banner);
1480     banner_pad = (79 - banner_len) / 2;
1481     memset(banner, ' ', banner_pad);
1482 
1483 #ifdef __linux__
1484     if (afl->fsrv.nyx_mode) {
1485 
1486       sprintf(banner + banner_pad,
1487               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
1488               afl->crash_mode ? cPIN "Mozzarbella Pizzeria table booking system"
1489                               : cYEL "Mozzarbella Pizzeria management system",
1490               si, afl->use_banner, afl->power_name);
1491 
1492     } else {
1493 
1494 #endif
1495       sprintf(banner + banner_pad,
1496               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
1497               afl->crash_mode ? cPIN "Mozzarbella Pizzeria table booking system"
1498                               : cYEL "Mozzarbella Pizzeria management system",
1499               si, afl->use_banner, afl->power_name);
1500 
1501 #ifdef __linux__
1502 
1503     }
1504 
1505 #endif
1506 
1507   }
1508 
1509   SAYF("\n%s\n", banner);
1510 
1511   /* "Handy" shortcuts for drawing boxes... */
1512 
1513 #define bSTG bSTART cGRA
1514 #define bH2 bH bH
1515 #define bH5 bH2 bH2 bH
1516 #define bH10 bH5 bH5
1517 #define bH20 bH10 bH10
1518 #define bH30 bH20 bH10
1519 #define SP5 "     "
1520 #define SP10 SP5 SP5
1521 #define SP20 SP10 SP10
1522 
1523   /* Since `total_crashes` does not get reloaded from disk on restart,
1524     it indicates if we found crashes this round already -> paint red.
1525     If it's 0, but `saved_crashes` is set from a past run, paint in yellow. */
1526   char *crash_color = afl->total_crashes   ? cLRD
1527                       : afl->saved_crashes ? cYEL
1528                                            : cRST;
1529 
1530   /* Lord, forgive me this. */
1531 
1532   SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
1533        " Mozzarbella has been proudly serving pizzas since " bSTG bH20 bH bH bH
1534            bHB bH bSTOP cCYA " In this time, we served " bSTG bH30 bRT "\n");
1535 
1536   if (afl->non_instrumented_mode) {
1537 
1538     strcpy(tmp, cRST);
1539 
1540   } else {
1541 
1542     u64 min_wo_finds = (cur_ms - afl->last_find_time) / 1000 / 60;
1543 
1544     /* First queue cycle: don't stop now! */
1545     if (afl->queue_cycle == 1 || min_wo_finds < 15) {
1546 
1547       strcpy(tmp, cMGN);
1548 
1549     } else
1550 
1551         /* Subsequent cycles, but we're still making finds. */
1552         if (afl->cycles_wo_finds < 25 || min_wo_finds < 30) {
1553 
1554       strcpy(tmp, cYEL);
1555 
1556     } else
1557 
1558         /* No finds for a long time and no test cases to try. */
1559         if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed &&
1560             min_wo_finds > 120) {
1561 
1562       strcpy(tmp, cLGN);
1563 
1564       /* Default: cautiously OK to stop? */
1565 
1566     } else {
1567 
1568       strcpy(tmp, cLBL);
1569 
1570     }
1571 
1572   }
1573 
1574   u_stringify_time_diff(time_tmp, afl->prev_run_time + cur_ms, afl->start_time);
1575   SAYF(bV                                                               bSTOP
1576        "                         open time : " cRST "%-37s " bSTG bV    bSTOP
1577        "                     seasons done : %s%-5s               " bSTG bV "\n",
1578        time_tmp, tmp, u_stringify_int(IB(0), afl->queue_cycle - 1));
1579 
1580   /* We want to warn people about not seeing new paths after a full cycle,
1581      except when resuming fuzzing or running in non-instrumented mode. */
1582 
1583   if (!afl->non_instrumented_mode &&
1584       (afl->last_find_time || afl->resuming_fuzz || afl->queue_cycle == 1 ||
1585        afl->in_bitmap || afl->crash_mode)) {
1586 
1587     u_stringify_time_diff(time_tmp, cur_ms, afl->last_find_time);
1588     SAYF(bV bSTOP "                  last pizza baked : " cRST "%-37s ",
1589          time_tmp);
1590 
1591   } else {
1592 
1593     if (afl->non_instrumented_mode) {
1594 
1595       SAYF(bV bSTOP "                  last pizza baked : " cPIN "n/a" cRST
1596                     " (non-instrumented mode)           ");
1597 
1598     } else {
1599 
1600       SAYF(bV bSTOP "                  last pizza baked : " cRST
1601                     "none yet " cLRD
1602                     "(odd, check Gennarino, he might be slacking!)     ");
1603 
1604     }
1605 
1606   }
1607 
1608   SAYF(bSTG bV bSTOP "               pizzas on the menu : " cRST
1609                      "%-5s               " bSTG bV "\n",
1610        u_stringify_int(IB(0), afl->queued_items));
1611 
1612   /* Highlight crashes in red if found, denote going over the KEEP_UNIQUE_CRASH
1613      limit with a '+' appended to the count. */
1614 
1615   sprintf(tmp, "%s%s", u_stringify_int(IB(0), afl->saved_crashes),
1616           (afl->saved_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
1617 
1618   u_stringify_time_diff(time_tmp, cur_ms, afl->last_crash_time);
1619   SAYF(bV                                                                bSTOP
1620        "                last ordered pizza : " cRST "%-33s     " bSTG bV bSTOP
1621        "                         at table : %s%-6s              " bSTG bV "\n",
1622        time_tmp, crash_color, tmp);
1623 
1624   sprintf(tmp, "%s%s", u_stringify_int(IB(0), afl->saved_hangs),
1625           (afl->saved_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
1626 
1627   u_stringify_time_diff(time_tmp, cur_ms, afl->last_hang_time);
1628   SAYF(bV                                                                bSTOP
1629        "  last conversation with customers : " cRST "%-33s     " bSTG bV bSTOP
1630        "                 number of Peroni : " cRST "%-6s              " bSTG bV
1631        "\n",
1632        time_tmp, tmp);
1633 
1634   SAYF(bVR bH bSTOP                                           cCYA
1635        " Baking progress  " bSTG bH30 bH20 bH5 bH bX bH bSTOP cCYA
1636        " Pizzeria busyness" bSTG bH30 bH5 bH bH               bVL "\n");
1637 
1638   /* This gets funny because we want to print several variable-length variables
1639      together, but then cram them into a fixed-width field - so we need to
1640      put them in a temporary buffer first. */
1641 
1642   sprintf(tmp, "%s%s%u (%0.01f%%)", u_stringify_int(IB(0), afl->current_entry),
1643           afl->queue_cur->favored ? "." : "*", afl->queue_cur->fuzz_level,
1644           ((double)afl->current_entry * 100) / afl->queued_items);
1645 
1646   SAYF(bV bSTOP "                        now baking : " cRST
1647                 "%-18s                    " bSTG bV bSTOP,
1648        tmp);
1649 
1650   sprintf(tmp, "%0.02f%% / %0.02f%%",
1651           ((double)afl->queue_cur->bitmap_size) * 100 / afl->fsrv.real_map_size,
1652           t_byte_ratio);
1653 
1654   SAYF("                       table full : %s%-19s " bSTG bV "\n",
1655        t_byte_ratio > 70
1656            ? cLRD
1657            : ((t_bytes < 200 && !afl->non_instrumented_mode) ? cPIN : cRST),
1658        tmp);
1659 
1660   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_items),
1661           ((double)afl->cur_skipped_items * 100) / afl->queued_items);
1662 
1663   SAYF(bV bSTOP "                     burned pizzas : " cRST
1664                 "%-18s                    " bSTG bV,
1665        tmp);
1666 
1667   sprintf(tmp, "%0.02f bits/tuple", t_bytes ? (((double)t_bits) / t_bytes) : 0);
1668 
1669   SAYF(bSTOP "                   count coverage : " cRST "%-19s " bSTG bV "\n",
1670        tmp);
1671 
1672   SAYF(bVR bH bSTOP                                              cCYA
1673        " Pizzas almost ready " bSTG bH30 bH20 bH2 bH bX bH bSTOP cCYA
1674        " Types of pizzas cooking " bSTG bH10 bH5 bH2 bH10 bH2 bH bVL "\n");
1675 
1676   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
1677           ((double)afl->queued_favored) * 100 / afl->queued_items);
1678 
1679   /* Yeah... it's still going on... halp? */
1680 
1681   SAYF(bV bSTOP "                     now preparing : " cRST
1682                 "%-22s                " bSTG bV                          bSTOP
1683                 "                favourite topping : " cRST "%-20s" bSTG bV
1684                 "\n",
1685        afl->stage_name, tmp);
1686 
1687   if (!afl->stage_max) {
1688 
1689     sprintf(tmp, "%s/-", u_stringify_int(IB(0), afl->stage_cur));
1690 
1691   } else {
1692 
1693     sprintf(tmp, "%s/%s (%0.02f%%)", u_stringify_int(IB(0), afl->stage_cur),
1694             u_stringify_int(IB(1), afl->stage_max),
1695             ((double)afl->stage_cur) * 100 / afl->stage_max);
1696 
1697   }
1698 
1699   SAYF(bV bSTOP "                  number of pizzas : " cRST
1700                 "%-23s               " bSTG bV bSTOP,
1701        tmp);
1702 
1703   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_with_cov),
1704           ((double)afl->queued_with_cov) * 100 / afl->queued_items);
1705 
1706   SAYF(" new pizza type seen on Instagram : " cRST "%-20s" bSTG bV "\n", tmp);
1707 
1708   sprintf(tmp, "%s (%s%s saved)", u_stringify_int(IB(0), afl->total_crashes),
1709           u_stringify_int(IB(1), afl->saved_crashes),
1710           (afl->saved_crashes >= KEEP_UNIQUE_CRASH) ? "+" : "");
1711 
1712   if (afl->crash_mode) {
1713 
1714     SAYF(bV bSTOP "                      total pizzas : " cRST
1715                   "%-22s                " bSTG bV              bSTOP
1716                   "      pizzas with pineapple : %s%-20s" bSTG bV "\n",
1717          u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
1718 
1719   } else {
1720 
1721     SAYF(bV bSTOP "                      total pizzas : " cRST
1722                   "%-22s                " bSTG bV                    bSTOP
1723                   "      total pizzas with pineapple : %s%-20s" bSTG bV "\n",
1724          u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
1725 
1726   }
1727 
1728   /* Show a warning about slow execution. */
1729 
1730   if (afl->stats_avg_exec < 100) {
1731 
1732     sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec),
1733             afl->stats_avg_exec < 20 ? "zzzz..." : "Gennarino is at it again!");
1734 
1735     SAYF(bV bSTOP "                pizza making speed : " cLRD
1736                   "%-22s                ",
1737          tmp);
1738 
1739   } else {
1740 
1741     sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec));
1742     SAYF(bV bSTOP "                pizza making speed : " cRST
1743                   "%-22s                ",
1744          tmp);
1745 
1746   }
1747 
1748   sprintf(tmp, "%s (%s%s saved)", u_stringify_int(IB(0), afl->total_tmouts),
1749           u_stringify_int(IB(1), afl->saved_tmouts),
1750           (afl->saved_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
1751 
1752   SAYF(bSTG bV bSTOP "                    burned pizzas : " cRST "%-20s" bSTG bV
1753                      "\n",
1754        tmp);
1755 
1756   /* Aaaalmost there... hold on! */
1757 
1758   SAYF(bVR bH cCYA bSTOP " Promotional campaign on TikTok yields " bSTG bH30 bH2
1759            bH bH2 bX bH bSTOP                                       cCYA
1760                          " Customer type " bSTG bH5 bH2 bH30 bH2 bH bVL "\n");
1761 
1762   if (unlikely(afl->custom_only)) {
1763 
1764     strcpy(tmp, "oven off (custom-mutator-only mode)");
1765 
1766   } else if (likely(afl->skip_deterministic)) {
1767 
1768     strcpy(tmp, "oven off (default, enable with -D)");
1769 
1770   } else {
1771 
1772     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
1773             u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP1]),
1774             u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP1]),
1775             u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP2]),
1776             u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP2]),
1777             u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP4]),
1778             u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP4]));
1779 
1780   }
1781 
1782   SAYF(bV                                                                 bSTOP
1783        "                pizzas for celiac  : " cRST "%-36s  " bSTG bV     bSTOP
1784        "                           levels : " cRST "%-10s          " bSTG bV
1785        "\n",
1786        tmp, u_stringify_int(IB(0), afl->max_depth));
1787 
1788   if (unlikely(!afl->skip_deterministic)) {
1789 
1790     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
1791             u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]),
1792             u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]),
1793             u_stringify_int(IB(2), afl->stage_finds[STAGE_FLIP16]),
1794             u_stringify_int(IB(3), afl->stage_cycles[STAGE_FLIP16]),
1795             u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]),
1796             u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32]));
1797 
1798   }
1799 
1800   SAYF(bV                                                                 bSTOP
1801        "                   pizzas for kids : " cRST "%-36s  " bSTG bV     bSTOP
1802        "                   pizzas to make : " cRST "%-10s          " bSTG bV
1803        "\n",
1804        tmp, u_stringify_int(IB(0), afl->pending_not_fuzzed));
1805 
1806   if (unlikely(!afl->skip_deterministic)) {
1807 
1808     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
1809             u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]),
1810             u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]),
1811             u_stringify_int(IB(2), afl->stage_finds[STAGE_ARITH16]),
1812             u_stringify_int(IB(3), afl->stage_cycles[STAGE_ARITH16]),
1813             u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]),
1814             u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32]));
1815 
1816   }
1817 
1818   SAYF(bV                                                                 bSTOP
1819        "                      pizza bianca : " cRST "%-36s  " bSTG bV     bSTOP
1820        "                       nice table : " cRST "%-10s          " bSTG bV
1821        "\n",
1822        tmp, u_stringify_int(IB(0), afl->pending_favored));
1823 
1824   if (unlikely(!afl->skip_deterministic)) {
1825 
1826     sprintf(tmp, "%s/%s, %s/%s, %s/%s",
1827             u_stringify_int(IB(0), afl->stage_finds[STAGE_INTEREST8]),
1828             u_stringify_int(IB(1), afl->stage_cycles[STAGE_INTEREST8]),
1829             u_stringify_int(IB(2), afl->stage_finds[STAGE_INTEREST16]),
1830             u_stringify_int(IB(3), afl->stage_cycles[STAGE_INTEREST16]),
1831             u_stringify_int(IB(4), afl->stage_finds[STAGE_INTEREST32]),
1832             u_stringify_int(IB(5), afl->stage_cycles[STAGE_INTEREST32]));
1833 
1834   }
1835 
1836   SAYF(bV                                                                 bSTOP
1837        "               recurring customers : " cRST "%-36s  " bSTG bV     bSTOP
1838        "                    new customers : " cRST "%-10s          " bSTG bV
1839        "\n",
1840        tmp, u_stringify_int(IB(0), afl->queued_discovered));
1841 
1842   if (unlikely(!afl->skip_deterministic)) {
1843 
1844     sprintf(tmp, "%s/%s, %s/%s, %s/%s, %s/%s",
1845             u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
1846             u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
1847             u_stringify_int(IB(2), afl->stage_finds[STAGE_EXTRAS_UI]),
1848             u_stringify_int(IB(3), afl->stage_cycles[STAGE_EXTRAS_UI]),
1849             u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
1850             u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]),
1851             u_stringify_int(IB(6), afl->stage_finds[STAGE_EXTRAS_AI]),
1852             u_stringify_int(IB(7), afl->stage_cycles[STAGE_EXTRAS_AI]));
1853 
1854   } else if (unlikely(!afl->extras_cnt || afl->custom_only)) {
1855 
1856     strcpy(tmp, "n/a");
1857 
1858   } else {
1859 
1860     strcpy(tmp, "18 year aniversary mode");
1861 
1862   }
1863 
1864   SAYF(bV                                                                 bSTOP
1865        "                        dictionary : " cRST "%-36s  " bSTG bV     bSTOP
1866        "       patrons from old resturant : " cRST "%-10s          " bSTG bV
1867        "\n",
1868        tmp,
1869        afl->sync_id ? u_stringify_int(IB(0), afl->queued_imported)
1870                     : (u8 *)"n/a");
1871 
1872   sprintf(tmp, "%s/%s, %s/%s",
1873           u_stringify_int(IB(0), afl->stage_finds[STAGE_HAVOC]),
1874           u_stringify_int(IB(2), afl->stage_cycles[STAGE_HAVOC]),
1875           u_stringify_int(IB(3), afl->stage_finds[STAGE_SPLICE]),
1876           u_stringify_int(IB(4), afl->stage_cycles[STAGE_SPLICE]));
1877 
1878   SAYF(bV bSTOP " 18 year anniversary mode/cleaning : " cRST
1879                 "%-36s  " bSTG bV bSTOP,
1880        tmp);
1881 
1882   if (t_bytes) {
1883 
1884     sprintf(tmp, "%0.02f%%", stab_ratio);
1885 
1886   } else {
1887 
1888     strcpy(tmp, "n/a");
1889 
1890   }
1891 
1892   SAYF("                    oven flameout : %s%-10s          " bSTG bV "\n",
1893        (stab_ratio < 85 && afl->var_byte_count > 40)
1894            ? cLRD
1895            : ((afl->queued_variable &&
1896                (!afl->persistent_mode || afl->var_byte_count > 20))
1897                   ? cMGN
1898                   : cRST),
1899        tmp);
1900 
1901   if (unlikely(afl->afl_env.afl_python_module)) {
1902 
1903     sprintf(tmp, "%s/%s,",
1904             u_stringify_int(IB(0), afl->stage_finds[STAGE_PYTHON]),
1905             u_stringify_int(IB(1), afl->stage_cycles[STAGE_PYTHON]));
1906 
1907   } else {
1908 
1909     strcpy(tmp, "unused,");
1910 
1911   }
1912 
1913   if (unlikely(afl->afl_env.afl_custom_mutator_library)) {
1914 
1915     strcat(tmp, " ");
1916     strcat(tmp, u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]));
1917     strcat(tmp, "/");
1918     strcat(tmp,
1919            u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
1920     strcat(tmp, ",");
1921 
1922   } else {
1923 
1924     strcat(tmp, " unused,");
1925 
1926   }
1927 
1928   if (unlikely(afl->shm.cmplog_mode)) {
1929 
1930     strcat(tmp, " ");
1931     strcat(tmp, u_stringify_int(IB(4), afl->stage_finds[STAGE_COLORIZATION]));
1932     strcat(tmp, "/");
1933     strcat(tmp, u_stringify_int(IB(5), afl->stage_cycles[STAGE_COLORIZATION]));
1934     strcat(tmp, ", ");
1935     strcat(tmp, u_stringify_int(IB(6), afl->stage_finds[STAGE_ITS]));
1936     strcat(tmp, "/");
1937     strcat(tmp, u_stringify_int(IB(7), afl->stage_cycles[STAGE_ITS]));
1938 
1939   } else {
1940 
1941     strcat(tmp, " unused, unused");
1942 
1943   }
1944 
1945   SAYF(bV bSTOP "                      py/custom/rq : " cRST
1946                 "%-36s  " bSTG bVR bH20 bH2 bH30 bH2 bH bH bRB "\n",
1947        tmp);
1948 
1949   if (likely(afl->disable_trim)) {
1950 
1951     sprintf(tmp, "disabled, ");
1952 
1953   } else if (unlikely(!afl->bytes_trim_out)) {
1954 
1955     sprintf(tmp, "n/a, ");
1956 
1957   } else {
1958 
1959     sprintf(tmp, "%0.02f%%/%s, ",
1960             ((double)(afl->bytes_trim_in - afl->bytes_trim_out)) * 100 /
1961                 afl->bytes_trim_in,
1962             u_stringify_int(IB(0), afl->trim_execs));
1963 
1964   }
1965 
1966   if (likely(afl->skip_deterministic)) {
1967 
1968     strcat(tmp, "disabled");
1969 
1970   } else if (unlikely(!afl->blocks_eff_total)) {
1971 
1972     strcat(tmp, "n/a");
1973 
1974   } else {
1975 
1976     u8 tmp2[128];
1977 
1978     sprintf(tmp2, "%0.02f%%",
1979             ((double)(afl->blocks_eff_total - afl->blocks_eff_select)) * 100 /
1980                 afl->blocks_eff_total);
1981 
1982     strcat(tmp, tmp2);
1983 
1984   }
1985 
1986   // if (afl->custom_mutators_count) {
1987 
1988   //
1989   //  sprintf(tmp, "%s/%s",
1990   //          u_stringify_int(IB(0), afl->stage_finds[STAGE_CUSTOM_MUTATOR]),
1991   //          u_stringify_int(IB(1), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
1992   //  SAYF(bV bSTOP " custom mut. : " cRST "%-36s " bSTG bV RESET_G1, tmp);
1993   //
1994   //} else {
1995 
1996   SAYF(bV bSTOP "                   toilets clogged : " cRST
1997                 "%-36s  " bSTG bV RESET_G1,
1998        tmp);
1999 
2000   //}
2001 
2002   /* Provide some CPU utilization stats. */
2003 
2004   if (afl->cpu_core_count) {
2005 
2006     char *spacing = SP10, snap[80] = " " cLGN "Pizzaioli's busyness " cRST " ";
2007 
2008     double cur_runnable = get_runnable_processes();
2009     u32    cur_utilization = cur_runnable * 100 / afl->cpu_core_count;
2010 
2011     u8 *cpu_color = cCYA;
2012 
2013     /* If we could still run one or more processes, use green. */
2014 
2015     if (afl->cpu_core_count > 1 && cur_runnable + 1 <= afl->cpu_core_count) {
2016 
2017       cpu_color = cLGN;
2018 
2019     }
2020 
2021     /* If we're clearly oversubscribed, use red. */
2022 
2023     if (!afl->no_cpu_meter_red && cur_utilization >= 150) { cpu_color = cLRD; }
2024 
2025     if (afl->fsrv.snapshot) { spacing = snap; }
2026 
2027 #ifdef HAVE_AFFINITY
2028 
2029     if (afl->cpu_aff >= 0) {
2030 
2031       SAYF("%s" cGRA "[cpu%03u:%s%3u%%" cGRA "]\r" cRST, spacing,
2032            MIN(afl->cpu_aff, 999), cpu_color, MIN(cur_utilization, (u32)999));
2033 
2034     } else {
2035 
2036       SAYF("%s" cGRA "   [cpu:%s%3u%%" cGRA "]\r" cRST, spacing, cpu_color,
2037            MIN(cur_utilization, (u32)999));
2038 
2039     }
2040 
2041 #else
2042 
2043     SAYF("%s" cGRA "   [cpu:%s%3u%%" cGRA "]\r" cRST, spacing, cpu_color,
2044          MIN(cur_utilization, (u32)999));
2045 
2046 #endif                                                    /* ^HAVE_AFFINITY */
2047 
2048   } else {
2049 
2050     SAYF("\r");
2051 
2052   }
2053 
2054   /* Last line */
2055   SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bH20 bH2 bH bRB bSTOP cRST RESET_G1);
2056 
2057 #undef IB
2058 
2059   /* Hallelujah! */
2060 
2061   fflush(0);
2062 
2063 }
2064 
2065 /* Display quick statistics at the end of processing the input directory,
2066    plus a bunch of warnings. Some calibration stuff also ended up here,
2067    along with several hardcoded constants. Maybe clean up eventually. */
2068 
2069 void show_init_stats(afl_state_t *afl) {
2070 
2071   struct queue_entry *q;
2072   u32                 min_bits = 0, max_bits = 0, max_len = 0, count = 0, i;
2073   u64                 min_us = 0, max_us = 0;
2074   u64                 avg_us = 0;
2075 
2076   u8 val_bufs[4][STRINGIFY_VAL_SIZE_MAX];
2077 #define IB(i) val_bufs[(i)], sizeof(val_bufs[(i)])
2078 
2079   if (afl->total_cal_cycles) {
2080 
2081     avg_us = afl->total_cal_us / afl->total_cal_cycles;
2082 
2083   }
2084 
2085   for (i = 0; i < afl->queued_items; i++) {
2086 
2087     q = afl->queue_buf[i];
2088     if (unlikely(q->disabled)) { continue; }
2089 
2090     if (!min_us || q->exec_us < min_us) { min_us = q->exec_us; }
2091     if (q->exec_us > max_us) { max_us = q->exec_us; }
2092 
2093     if (!min_bits || q->bitmap_size < min_bits) { min_bits = q->bitmap_size; }
2094     if (q->bitmap_size > max_bits) { max_bits = q->bitmap_size; }
2095 
2096     if (q->len > max_len) { max_len = q->len; }
2097 
2098     ++count;
2099 
2100   }
2101 
2102   // SAYF("\n");
2103 
2104   if (avg_us > ((afl->fsrv.cs_mode || afl->fsrv.qemu_mode || afl->unicorn_mode)
2105                     ? 50000
2106                     : 10000)) {
2107 
2108     WARNF(cLRD "The target binary is pretty slow! See %s/perf_tips.md.",
2109           doc_path);
2110 
2111   }
2112 
2113   /* Let's keep things moving with slow binaries. */
2114 
2115   if (unlikely(afl->fixed_seed)) {
2116 
2117     afl->havoc_div = 1;
2118 
2119   } else if (avg_us > 50000) {
2120 
2121     afl->havoc_div = 10;                                /* 0-19 execs/sec   */
2122 
2123   } else if (avg_us > 20000) {
2124 
2125     afl->havoc_div = 5;                                 /* 20-49 execs/sec  */
2126 
2127   } else if (avg_us > 10000) {
2128 
2129     afl->havoc_div = 2;                                 /* 50-100 execs/sec */
2130 
2131   }
2132 
2133   if (!afl->resuming_fuzz) {
2134 
2135     if (max_len > 50 * 1024) {
2136 
2137       WARNF(cLRD "Some test cases are huge (%s) - see %s/perf_tips.md!",
2138             stringify_mem_size(IB(0), max_len), doc_path);
2139 
2140     } else if (max_len > 10 * 1024) {
2141 
2142       WARNF("Some test cases are big (%s) - see %s/perf_tips.md.",
2143             stringify_mem_size(IB(0), max_len), doc_path);
2144 
2145     }
2146 
2147     if (afl->useless_at_start && !afl->in_bitmap) {
2148 
2149       WARNF(cLRD "Some test cases look useless. Consider using a smaller set.");
2150 
2151     }
2152 
2153     if (afl->queued_items > 100) {
2154 
2155       WARNF(cLRD
2156             "You probably have far too many input files! Consider trimming "
2157             "down.");
2158 
2159     } else if (afl->queued_items > 20) {
2160 
2161       WARNF("You have lots of input files; try starting small.");
2162 
2163     }
2164 
2165   }
2166 
2167   OKF("Here are some useful stats:\n\n"
2168 
2169       cGRA "    Test case count : " cRST
2170       "%u favored, %u variable, %u ignored, %u total\n" cGRA
2171       "       Bitmap range : " cRST
2172       "%u to %u bits (average: %0.02f bits)\n" cGRA
2173       "        Exec timing : " cRST "%s to %s us (average: %s us)\n",
2174       afl->queued_favored, afl->queued_variable, afl->queued_items - count,
2175       afl->queued_items, min_bits, max_bits,
2176       ((double)afl->total_bitmap_size) /
2177           (afl->total_bitmap_entries ? afl->total_bitmap_entries : 1),
2178       stringify_int(IB(0), min_us), stringify_int(IB(1), max_us),
2179       stringify_int(IB(2), avg_us));
2180 
2181   if (afl->timeout_given != 1) {
2182 
2183     /* Figure out the appropriate timeout. The basic idea is: 5x average or
2184        1x max, rounded up to EXEC_TM_ROUND ms and capped at 1 second.
2185 
2186        If the program is slow, the multiplier is lowered to 2x or 3x, because
2187        random scheduler jitter is less likely to have any impact, and because
2188        our patience is wearing thin =) */
2189 
2190     if (unlikely(afl->fixed_seed)) {
2191 
2192       afl->fsrv.exec_tmout = avg_us * 5 / 1000;
2193 
2194     } else if (avg_us > 50000) {
2195 
2196       afl->fsrv.exec_tmout = avg_us * 2 / 1000;
2197 
2198     } else if (avg_us > 10000) {
2199 
2200       afl->fsrv.exec_tmout = avg_us * 3 / 1000;
2201 
2202     } else {
2203 
2204       afl->fsrv.exec_tmout = avg_us * 5 / 1000;
2205 
2206     }
2207 
2208     afl->fsrv.exec_tmout = MAX(afl->fsrv.exec_tmout, max_us / 1000);
2209     afl->fsrv.exec_tmout =
2210         (afl->fsrv.exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND;
2211 
2212     if (afl->fsrv.exec_tmout > EXEC_TIMEOUT) {
2213 
2214       afl->fsrv.exec_tmout = EXEC_TIMEOUT;
2215 
2216     }
2217 
2218     ACTF("No -t option specified, so I'll use an exec timeout of %u ms.",
2219          afl->fsrv.exec_tmout);
2220 
2221     afl->timeout_given = 1;
2222 
2223   } else if (afl->timeout_given == 3) {
2224 
2225     ACTF("Applying timeout settings from resumed session (%u ms).",
2226          afl->fsrv.exec_tmout);
2227 
2228   } else {
2229 
2230     ACTF("-t option specified. We'll use an exec timeout of %u ms.",
2231          afl->fsrv.exec_tmout);
2232 
2233   }
2234 
2235   /* In non-instrumented mode, re-running every timing out test case with a
2236      generous time
2237      limit is very expensive, so let's select a more conservative default. */
2238 
2239   if (afl->non_instrumented_mode && !(afl->afl_env.afl_hang_tmout)) {
2240 
2241     afl->hang_tmout = MIN((u32)EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100);
2242 
2243   }
2244 
2245   OKF("All set and ready to roll!");
2246 #undef IB
2247 
2248 }
2249 
2250