mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-22 14:49:45 -04:00
DEBUG: add a new WARN_ON_ONCE() macro
This one will maintain a static counter per call place and will only emit the warning on the first call. It may be used to invite users to report an unexpected event without spamming them with messages.
This commit is contained in:
parent
a79db30c63
commit
4e0a8b1224
2 changed files with 45 additions and 4 deletions
|
|
@ -72,19 +72,46 @@
|
|||
__bug_cond; /* let's return the condition */ \
|
||||
})
|
||||
|
||||
/* This one is equivalent except that it only emits the message once by
|
||||
* maintaining a static counter. This may be used with warnings to detect
|
||||
* certain unexpected conditions in field. Later on, in cores it will be
|
||||
* possible to verify these counters.
|
||||
*/
|
||||
#define _BUG_ON_ONCE(cond, file, line, crash, pfx, sfx) \
|
||||
__BUG_ON_ONCE(cond, file, line, crash, pfx, sfx)
|
||||
|
||||
#define __BUG_ON_ONCE(cond, file, line, crash, pfx, sfx) \
|
||||
({ \
|
||||
static int __match_count_##line; \
|
||||
int __bug_cond = !!(cond); \
|
||||
if (unlikely(__bug_cond) && \
|
||||
!_HA_ATOMIC_FETCH_ADD(&__match_count_##line, 1)) { \
|
||||
const char msg[] = "\n" pfx "condition \"" #cond "\" matched at " file ":" #line "" sfx "\n"; \
|
||||
DISGUISE(write(2, msg, __builtin_strlen(msg))); \
|
||||
if (crash) \
|
||||
ABORT_NOW(); \
|
||||
else \
|
||||
DUMP_TRACE(); \
|
||||
} \
|
||||
__bug_cond; /* let's return the condition */ \
|
||||
})
|
||||
|
||||
/* BUG_ON: complains if <cond> is true when DEBUG_STRICT or DEBUG_STRICT_NOCRASH
|
||||
* are set, does nothing otherwise. With DEBUG_STRICT in addition it immediately
|
||||
* crashes using ABORT_NOW() above.
|
||||
*/
|
||||
#if defined(DEBUG_STRICT)
|
||||
#define BUG_ON(cond) _BUG_ON(cond, __FILE__, __LINE__, 1, "FATAL: bug ", "")
|
||||
#define WARN_ON(cond) _BUG_ON(cond, __FILE__, __LINE__, 0, "WARNING: ", " (please report to developers)")
|
||||
#define BUG_ON(cond) _BUG_ON (cond, __FILE__, __LINE__, 1, "FATAL: bug ", "")
|
||||
#define WARN_ON(cond) _BUG_ON (cond, __FILE__, __LINE__, 0, "WARNING: ", " (please report to developers)")
|
||||
#define WARN_ON_ONCE(cond) _BUG_ON_ONCE(cond, __FILE__, __LINE__, 0, "WARNING: ", " (please report to developers)")
|
||||
#elif defined(DEBUG_STRICT_NOCRASH)
|
||||
#define BUG_ON(cond) _BUG_ON(cond, __FILE__, __LINE__, 0, "FATAL: bug ", " (not crashing but process is untrusted now)")
|
||||
#define WARN_ON(cond) _BUG_ON(cond, __FILE__, __LINE__, 0, "WARNING: ", " (please report to developers)")
|
||||
#define BUG_ON(cond) _BUG_ON (cond, __FILE__, __LINE__, 0, "FATAL: bug ", " (not crashing but process is untrusted now)")
|
||||
#define WARN_ON(cond) _BUG_ON (cond, __FILE__, __LINE__, 0, "WARNING: ", " (please report to developers)")
|
||||
#define WARN_ON_ONCE(cond) _BUG_ON_ONCE(cond, __FILE__, __LINE__, 0, "WARNING: ", " (please report to developers)")
|
||||
#else
|
||||
#define BUG_ON(cond)
|
||||
#define WARN_ON(cond)
|
||||
#define WARN_ON_ONCE(cond)
|
||||
#endif
|
||||
|
||||
/* When not optimizing, clang won't remove that code, so only compile it in when optimizing */
|
||||
|
|
|
|||
14
src/debug.c
14
src/debug.c
|
|
@ -376,6 +376,19 @@ int debug_parse_cli_warn(char **args, char *payload, struct appctx *appctx, void
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* parse a "debug dev warn1" command. It always returns 1.
|
||||
* Note: we make sure not to make the function static so that it appears in the trace.
|
||||
*/
|
||||
int debug_parse_cli_warn1(char **args, char *payload, struct appctx *appctx, void *private)
|
||||
{
|
||||
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
|
||||
return 1;
|
||||
|
||||
_HA_ATOMIC_INC(&debug_commands_issued);
|
||||
WARN_ON_ONCE(one > zero);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* parse a "debug dev close" command. It always returns 1. */
|
||||
static int debug_parse_cli_close(char **args, char *payload, struct appctx *appctx, void *private)
|
||||
{
|
||||
|
|
@ -1404,6 +1417,7 @@ static struct cli_kw_list cli_kws = {{ },{
|
|||
{{ "debug", "dev", "sym", NULL }, "debug dev sym <addr> : resolve symbol address", debug_parse_cli_sym, NULL, NULL, NULL, ACCESS_EXPERT },
|
||||
{{ "debug", "dev", "tkill", NULL }, "debug dev tkill [thr] [sig] : send signal to thread", debug_parse_cli_tkill, NULL, NULL, NULL, ACCESS_EXPERT },
|
||||
{{ "debug", "dev", "warn", NULL }, "debug dev warn : call WARN_ON() and possibly crash", debug_parse_cli_warn, NULL, NULL, NULL, ACCESS_EXPERT },
|
||||
{{ "debug", "dev", "warn1", NULL }, "debug dev warn1 : call WARN_ON_ONCE() and possibly crash", debug_parse_cli_warn1, NULL, NULL, NULL, ACCESS_EXPERT },
|
||||
{{ "debug", "dev", "write", NULL }, "debug dev write [size] : write that many bytes in return", debug_parse_cli_write, NULL, NULL, NULL, ACCESS_EXPERT },
|
||||
#if defined(HA_HAVE_DUMP_LIBS)
|
||||
{{ "show", "libs", NULL, NULL }, "show libs : show loaded object files and libraries", debug_parse_cli_show_libs, NULL, NULL },
|
||||
|
|
|
|||
Loading…
Reference in a new issue