# DEBUG_NO_POOLS, DEBUG_FAIL_ALLOC, DEBUG_STRICT_ACTION=[0-3], DEBUG_HPACK,
# DEBUG_AUTH, DEBUG_SPOE, DEBUG_UAF, DEBUG_THREAD, DEBUG_STRICT, DEBUG_DEV,
# DEBUG_TASK, DEBUG_MEMORY_POOLS, DEBUG_POOL_TRACING, DEBUG_QPACK, DEBUG_LIST,
-# DEBUG_COUNTERS=[0-1], DEBUG_STRESS, DEBUG_UNIT.
+# DEBUG_COUNTERS=[0-2], DEBUG_STRESS, DEBUG_UNIT.
DEBUG =
#### Trace options
* Debugging
- anonkey
+ - debug.counters
- force-cfg-parser-pause
- quiet
- warn-blocked-traffic-after
from the CLI command "set anon global-key". See also command line argument
"-dC" in the management manual.
+debug.counters { on | off }
+ Enables ('on') or disables ('off') the updating of event counters in the
+ code. These are the counters reported under the type "CNT" in the CLI command
+ "debug counters". These counters are only available when the code was build
+ with DEBUG_COUNTERS set to a value 1 or above. With the value 1, the counters
+ are not updated by default ("debug.counters off"), and with value 2, they are
+ updated by default ("debug.counters on"). There is normally no reason to
+ change this setting unless a developer requests it, or unless it is suspected
+ to consume abnormal amounts of CPU (in which case a report to developers is
+ necessary with a dump of the counters). It is also possible to change this
+ status at run time using the "debug counters" CLI command. Please consult the
+ management manual.
+
force-cfg-parser-pause <timeout>
This command is pausing the configuration parser for <timeout> milliseconds.
This is useful for development or for testing timeouts of init scripts,
See also "new ssl crl-file", "set ssl crl-file", "abort ssl crl-file" and
"add ssl crt-list".
-debug counters [reset|show|all|bug|chk|cnt|glt|?]*
+debug counters [reset|show|on|off|all|bug|chk|cnt|glt|?]*
List internal counters placed in the code, which may vary depending on some
build options. Some of them depend on DEBUG_STRICT, others on DEBUG_COUNTERS.
The command takes a combination of multiple arguments, some defining actions
- chk enables listing the counters for CHECK_IF() statements
- glt enables listing the counters for COUNT_GLITCH() statements
- all enables showing counters that never triggered (value 0)
+ - off action: disables updating of the COUNT_IF() counters
+ - on action: enables updating of the COUNT_IF() counters
- reset action: resets all specified counters
- show action: shows all specified counters
* COUNT_IF() invocation requires a special section ("dbg_cnt") hence a modern
* linker.
*/
+extern unsigned int debug_enable_counters;
+
#if !defined(USE_OBSOLETE_LINKER)
/* type of checks that can be verified. We cannot really distinguish between
/* Matrix for DEBUG_COUNTERS:
* 0 : only BUG_ON() and CHECK_IF() are reported (super rare)
- * 1 : COUNT_GLITCH() and COUNT_IF() are also reported (rare)
+ * 1 : COUNT_GLITCH() are also reported (rare)
+ * COUNT_IF() are also reported only if debug_enable_counters was set
+ * 2 : COUNT_IF() are also reported unless debug_enable_counters was reset
*/
/* Core of the COUNT_IF() macro, checks the condition and counts one hit if
- * true. It's only enabled at DEBUG_COUNTERS >= 1.
+ * true. It's only enabled at DEBUG_COUNTERS >= 1, and enabled by default if
+ * DEBUG_COUNTERS >= 2.
*/
# if defined(DEBUG_COUNTERS) && (DEBUG_COUNTERS >= 1)
-# define _COUNT_IF(cond, file, line, ...) \
- (unlikely(cond) ? ({ \
- __DBG_COUNT(cond, file, line, DBG_COUNT_IF, __VA_ARGS__); \
- 1; /* let's return the true condition */ \
+# define _COUNT_IF(cond, file, line, ...) \
+ (unlikely(cond) ? ({ \
+ if (debug_enable_counters) \
+ __DBG_COUNT(cond, file, line, DBG_COUNT_IF, __VA_ARGS__); \
+ 1; /* let's return the true condition */ \
}) : 0)
# else
# define _COUNT_IF(cond, file, line, ...) DISGUISE(unlikely(cond) ? 1 : 0)
#include <haproxy/api.h>
#include <haproxy/applet.h>
#include <haproxy/buf.h>
+#include <haproxy/cfgparse.h>
#include <haproxy/cli.h>
#include <haproxy/clock.h>
#include <haproxy/debug.h>
unsigned int debug_commands_issued = 0;
unsigned int warn_blocked_issued = 0;
+unsigned int debug_enable_counters = (DEBUG_COUNTERS >= 2);
/* dumps a backtrace of the current thread that is appended to buffer <buf>.
* Lines are prefixed with the string <prefix> which may be empty (used for
action = 1;
continue;
}
+ else if (strcmp(args[arg], "off") == 0) {
+ action = 2;
+ continue;
+ }
+ else if (strcmp(args[arg], "on") == 0) {
+ action = 3;
+ continue;
+ }
else if (strcmp(args[arg], "all") == 0) {
ctx->show_all = 1;
continue;
continue;
}
else
- return cli_err(appctx, "Expects an optional action ('reset','show'), optional types ('bug','chk','cnt','glt') and optionally 'all' to even dump null counters.\n");
+ return cli_err(appctx, "Expects an optional action ('reset','show','on','off'), optional types ('bug','chk','cnt','glt') and optionally 'all' to even dump null counters.\n");
}
#if (DEBUG_STRICT > 0) || (DEBUG_COUNTERS > 0)
}
return 1;
}
+ else if (action == 2 || action == 3) { // off/on
+ if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
+ return 1;
+ HA_ATOMIC_STORE(&debug_enable_counters, action == 3);
+ return 0;
+ }
/* OK it's a show, let's dump relevant counters */
return 0;
}
if (ptr->type < DBG_COUNTER_TYPES)
- chunk_appendf(&trash, "%-10u %3s %s:%d %s()%s%s\n",
+ chunk_appendf(&trash, "%-10u %3s %s:%d %s()%s%s%s\n",
ptr->count, bug_type[ptr->type],
name, ptr->line, ptr->func,
- *ptr->desc ? ": " : "", ptr->desc);
+ *ptr->desc ? ": " : "", ptr->desc,
+ (ptr->type == DBG_COUNT_IF && !debug_enable_counters) ? " (stopped)" : "");
if (applet_putchk(appctx, &trash) == -1) {
ctx->start = ptr;
#endif
+#if DEBUG_STRICT > 1
+/* config parser for global "debug.counters", accepts "on" or "off" */
+static int cfg_parse_debug_counters(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
+{
+ if (too_many_args(1, args, err, NULL))
+ return -1;
+
+ if (strcmp(args[1], "on") == 0) {
+ HA_ATOMIC_STORE(&debug_enable_counters, 1);
+ }
+ else if (strcmp(args[1], "off") == 0)
+ HA_ATOMIC_STORE(&debug_enable_counters, 0);
+ else {
+ memprintf(err, "'%s' expects either 'on' or 'off' but got '%s'.", args[0], args[1]);
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+/* config keyword parsers */
+static struct cfg_kw_list cfg_kws = {ILH, {
+#if DEBUG_STRICT > 1
+ { CFG_GLOBAL, "debug.counters", cfg_parse_debug_counters },
+#endif
+ { 0, NULL, NULL }
+}};
+INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
/* register cli keywords */
static struct cli_kw_list cli_kws = {{ },{