xref: /aosp_15_r20/external/AFLplusplus/include/debug.h (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1 /*
2    american fuzzy lop++ - debug / error handling macros
3    ----------------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Now maintained by Marc Heuse <[email protected]>,
8                      Heiko Eißfeldt <[email protected]>,
9                      Andrea Fioraldi <[email protected]>,
10                      Dominik Maier <[email protected]>
11 
12    Copyright 2016, 2017 Google Inc. All rights reserved.
13    Copyright 2019-2024 AFLplusplus Project. All rights reserved.
14 
15    Licensed under the Apache License, Version 2.0 (the "License");
16    you may not use this file except in compliance with the License.
17    You may obtain a copy of the License at:
18 
19      https://www.apache.org/licenses/LICENSE-2.0
20 
21  */
22 
23 #ifndef _HAVE_DEBUG_H
24 #define _HAVE_DEBUG_H
25 
26 #include <errno.h>
27 
28 #include "types.h"
29 #include "config.h"
30 
31 /*******************
32  * Terminal colors *
33  *******************/
34 
35 #ifndef MESSAGES_TO_STDOUT
36   #define MESSAGES_TO_STDOUT
37 #endif
38 
39 #ifdef USE_COLOR
40 
41   #define cBLK "\x1b[0;30m"
42   #define cRED "\x1b[0;31m"
43   #define cGRN "\x1b[0;32m"
44   #define cBRN "\x1b[0;33m"
45   #define cBLU "\x1b[0;34m"
46   #define cMGN "\x1b[0;35m"
47   #define cCYA "\x1b[0;36m"
48   #define cLGR "\x1b[0;37m"
49   #define cGRA "\x1b[1;90m"
50   #define cLRD "\x1b[1;91m"
51   #define cLGN "\x1b[1;92m"
52   #define cYEL "\x1b[1;93m"
53   #define cLBL "\x1b[1;94m"
54   #define cPIN "\x1b[1;95m"
55   #define cLCY "\x1b[1;96m"
56   #define cBRI "\x1b[1;97m"
57   #define cRST "\x1b[0m"
58 
59   #define bgBLK "\x1b[40m"
60   #define bgRED "\x1b[41m"
61   #define bgGRN "\x1b[42m"
62   #define bgBRN "\x1b[43m"
63   #define bgBLU "\x1b[44m"
64   #define bgMGN "\x1b[45m"
65   #define bgCYA "\x1b[46m"
66   #define bgLGR "\x1b[47m"
67   #define bgGRA "\x1b[100m"
68   #define bgLRD "\x1b[101m"
69   #define bgLGN "\x1b[102m"
70   #define bgYEL "\x1b[103m"
71   #define bgLBL "\x1b[104m"
72   #define bgPIN "\x1b[105m"
73   #define bgLCY "\x1b[106m"
74   #define bgBRI "\x1b[107m"
75 
76 #else
77 
78   #define cBLK ""
79   #define cRED ""
80   #define cGRN ""
81   #define cBRN ""
82   #define cBLU ""
83   #define cMGN ""
84   #define cCYA ""
85   #define cLGR ""
86   #define cGRA ""
87   #define cLRD ""
88   #define cLGN ""
89   #define cYEL ""
90   #define cLBL ""
91   #define cPIN ""
92   #define cLCY ""
93   #define cBRI ""
94   #define cRST ""
95 
96   #define bgBLK ""
97   #define bgRED ""
98   #define bgGRN ""
99   #define bgBRN ""
100   #define bgBLU ""
101   #define bgMGN ""
102   #define bgCYA ""
103   #define bgLGR ""
104   #define bgGRA ""
105   #define bgLRD ""
106   #define bgLGN ""
107   #define bgYEL ""
108   #define bgLBL ""
109   #define bgPIN ""
110   #define bgLCY ""
111   #define bgBRI ""
112 
113 #endif                                                        /* ^USE_COLOR */
114 
115 /*************************
116  * Box drawing sequences *
117  *************************/
118 
119 #ifdef FANCY_BOXES_NO_UTF
120 
121   #define SET_G1 "\x1b)0"                      /* Set G1 for box drawing    */
122   #define RESET_G1 "\x1b)B"                    /* Reset G1 to ASCII         */
123   #define bSTART "\x0e"                        /* Enter G1 drawing mode     */
124   #define bSTOP "\x0f"                         /* Leave G1 drawing mode     */
125   #define bH "q"                               /* Horizontal line           */
126   #define bV "x"                               /* Vertical line             */
127   #define bLT "l"                              /* Left top corner           */
128   #define bRT "k"                              /* Right top corner          */
129   #define bLB "m"                              /* Left bottom corner        */
130   #define bRB "j"                              /* Right bottom corner       */
131   #define bX "n"                               /* Cross                     */
132   #define bVR "t"                              /* Vertical, branch right    */
133   #define bVL "u"                              /* Vertical, branch left     */
134   #define bHT "v"                              /* Horizontal, branch top    */
135   #define bHB "w"                              /* Horizontal, branch bottom */
136 
137 #else
138 
139   #ifdef FANCY_BOXES
140 
141     #define SET_G1 ""
142     #define RESET_G1 ""
143     #define bSTART ""
144     #define bSTOP ""
145     #define bH "\u2500"                        /* Horizontal line           */
146     #define bV "\u2502"                        /* Vertical line             */
147     #define bLT "\u250c"                       /* Left top corner           */
148     #define bRT "\u2510"                       /* Right top corner          */
149     #define bLB "\u2514"                       /* Left bottom corner        */
150     #define bRB "\u2518"                       /* Right bottom corner       */
151     #define bX "\u253c"                        /* Cross                     */
152     #define bVR "\u251c"                       /* Vertical, branch right    */
153     #define bVL "\u2524"                       /* Vertical, branch left     */
154     #define bHT "\u2534"                       /* Horizontal, branch top    */
155     #define bHB "\u252c"                       /* Horizontal, branch bottom */
156 
157   #else
158 
159     #define SET_G1 ""
160     #define RESET_G1 ""
161     #define bSTART ""
162     #define bSTOP ""
163     #define bH "-"
164     #define bV "|"
165     #define bLT "+"
166     #define bRT "+"
167     #define bLB "+"
168     #define bRB "+"
169     #define bX "+"
170     #define bVR "+"
171     #define bVL "+"
172     #define bHT "+"
173     #define bHB "+"
174 
175   #endif
176 #endif                                                      /* ^FANCY_BOXES */
177 
178 /***********************
179  * Misc terminal codes *
180  ***********************/
181 
182 #define TERM_HOME "\x1b[H"
183 #define TERM_CLEAR TERM_HOME "\x1b[2J"
184 #define cEOL "\x1b[0K"
185 #define CURSOR_HIDE "\x1b[?25l"
186 #define CURSOR_SHOW "\x1b[?25h"
187 
188 /************************
189  * Debug & error macros *
190  ************************/
191 
192 #if defined USE_COLOR && !defined ALWAYS_COLORED
193   #include <unistd.h>
194   #pragma GCC diagnostic ignored "-Wformat-security"
colorfilter(const char * x)195 static inline const char *colorfilter(const char *x) {
196 
197   static int once = 1;
198   static int disabled = 0;
199 
200   if (once) {
201 
202     /* when there is no tty -> we always want filtering
203      * when AFL_NO_UI is set filtering depends on AFL_NO_COLOR
204      * otherwise we want always colors
205      */
206     disabled =
207         isatty(2) && (!getenv("AFL_NO_UI") ||
208                       (!getenv("AFL_NO_COLOR") && !getenv("AFL_NO_COLOUR")));
209     once = 0;
210 
211   }
212 
213   if (likely(disabled)) return x;
214 
215   static char monochromestring[4096];
216   char       *d = monochromestring;
217   int         in_seq = 0;
218 
219   while (*x) {
220 
221     if (in_seq && *x == 'm') {
222 
223       in_seq = 0;
224 
225     } else {
226 
227       if (!in_seq && *x == '\x1b') { in_seq = 1; }
228       if (!in_seq) { *d++ = *x; }
229 
230     }
231 
232     ++x;
233 
234   }
235 
236   *d = '\0';
237   return monochromestring;
238 
239 }
240 
241 #else
242   #define colorfilter(x) x                        /* no filtering necessary */
243 #endif
244 
245 /* macro magic to transform the first parameter to SAYF
246  * through colorfilter which strips coloring */
247 #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, \
248                   _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26,  \
249                   _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38,  \
250                   _39, _40, NAME, ...)                                         \
251   NAME
252 
253 #define SAYF(...)                                                           \
254   GET_MACRO(__VA_ARGS__, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N,    \
255             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
256             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
257             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
258             SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, SAYF_N, \
259             SAYF_N, SAYF_1)                                                 \
260   (__VA_ARGS__)
261 
262 #define SAYF_1(x) MY_SAYF(colorfilter(x))
263 #define SAYF_N(x, ...) MY_SAYF(colorfilter(x), __VA_ARGS__)
264 
265 /* Just print stuff to the appropriate stream. */
266 #ifdef MESSAGES_TO_STDOUT
267   #define MY_SAYF(x...) printf(x)
268 #else
269   #define MY_SAYF(x...) fprintf(stderr, x)
270 #endif                                               /* ^MESSAGES_TO_STDOUT */
271 
272 /* Show a prefixed warning. */
273 
274 #define WARNF(x...)                            \
275   do {                                         \
276                                                \
277     SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \
278     SAYF(cRST "\n");                           \
279                                                \
280   } while (0)
281 
282 /* Show a prefixed "doing something" message. */
283 
284 #define ACTF(x...)            \
285   do {                        \
286                               \
287     SAYF(cLBL "[*] " cRST x); \
288     SAYF(cRST "\n");          \
289                               \
290   } while (0)
291 
292 /* Show a prefixed "success" message. */
293 
294 #define OKF(x...)             \
295   do {                        \
296                               \
297     SAYF(cLGN "[+] " cRST x); \
298     SAYF(cRST "\n");          \
299                               \
300   } while (0)
301 
302 /* Show a prefixed fatal error message (not used in afl). */
303 
304 #define BADF(x...)              \
305   do {                          \
306                                 \
307     SAYF(cLRD "\n[-] " cRST x); \
308     SAYF(cRST "\n");            \
309                                 \
310   } while (0)
311 
312 /* Die with a verbose non-OS fatal error message. */
313 
314 #define FATAL(x...)                                                      \
315   do {                                                                   \
316                                                                          \
317     SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
318          "\n[-] PROGRAM ABORT : " cRST   x);                               \
319     SAYF(cLRD "\n         Location : " cRST "%s(), %s:%u\n\n", __func__, \
320          __FILE__, (u32)__LINE__);                                       \
321     exit(1);                                                             \
322                                                                          \
323   } while (0)
324 
325 /* Die by calling abort() to provide a core dump. */
326 
327 #define ABORT(x...)                                                      \
328   do {                                                                   \
329                                                                          \
330     SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
331          "\n[-] PROGRAM ABORT : " cRST   x);                               \
332     SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n\n", __func__, \
333          __FILE__, (u32)__LINE__);                                       \
334     abort();                                                             \
335                                                                          \
336   } while (0)
337 
338 /* Die while also including the output of perror(). */
339 
340 #define PFATAL(x...)                                                   \
341   do {                                                                 \
342                                                                        \
343     fflush(stdout);                                                    \
344     SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                          \
345          "\n[-]  SYSTEM ERROR : " cRST   x);                             \
346     SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n", __func__, \
347          __FILE__, (u32)__LINE__);                                     \
348     SAYF(cLRD "       OS message : " cRST "%s\n", strerror(errno));    \
349     exit(1);                                                           \
350                                                                        \
351   } while (0)
352 
353 /* Die with FATAL() or PFATAL() depending on the value of res (used to
354    interpret different failure modes for read(), write(), etc). */
355 
356 #define RPFATAL(res, x...) \
357   do {                     \
358                            \
359     if (res < 0)           \
360       PFATAL(x);           \
361     else                   \
362       FATAL(x);            \
363                            \
364   } while (0)
365 
366 /* Show a prefixed debug output. */
367 
368 #define DEBUGF(x...)                                    \
369   do {                                                  \
370                                                         \
371     fprintf(stderr, cMGN "[D] " cBRI "DEBUG: " cRST x); \
372     fprintf(stderr, cRST "");                           \
373                                                         \
374   } while (0)
375 
376 /* Error-checking versions of read() and write() that call RPFATAL() as
377    appropriate. */
378 
379 #define ck_write(fd, buf, len, fn)                                            \
380   do {                                                                        \
381                                                                               \
382     if (len <= 0) break;                                                      \
383     int _fd = (fd);                                                           \
384     s32 _written = 0, _off = 0, _len = (s32)(len);                            \
385                                                                               \
386     do {                                                                      \
387                                                                               \
388       s32 _res = write(_fd, (buf) + _off, _len);                              \
389       if (_res != _len && (_res > 0 && _written + _res != _len)) {            \
390                                                                               \
391         if (_res > 0) {                                                       \
392                                                                               \
393           _written += _res;                                                   \
394           _len -= _res;                                                       \
395           _off += _res;                                                       \
396                                                                               \
397         } else {                                                              \
398                                                                               \
399           RPFATAL(_res, "Short write to %s, fd %d (%d of %d bytes)", fn, _fd, \
400                   _res, _len);                                                \
401                                                                               \
402         }                                                                     \
403                                                                               \
404       } else {                                                                \
405                                                                               \
406         break;                                                                \
407                                                                               \
408       }                                                                       \
409                                                                               \
410     } while (1);                                                              \
411                                                                               \
412                                                                               \
413                                                                               \
414   } while (0)
415 
416 #define ck_read(fd, buf, len, fn)                              \
417   do {                                                         \
418                                                                \
419     s32 _len = (s32)(len);                                     \
420     s32 _res = read(fd, buf, _len);                            \
421     if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \
422                                                                \
423   } while (0)
424 
425 #endif                                                   /* ! _HAVE_DEBUG_H */
426 
427