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