diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h index 2f5d7b1d3..a13d0eb7c 100644 --- a/include/haproxy/pool.h +++ b/include/haproxy/pool.h @@ -108,6 +108,7 @@ void *pool_alloc_nocache(struct pool_head *pool); void pool_free_nocache(struct pool_head *pool, void *ptr); void dump_pools_to_trash(void); void dump_pools(void); +int pool_parse_debugging(const char *str, char **err); int pool_total_failures(void); unsigned long pool_total_allocated(void); unsigned long pool_total_used(void); diff --git a/src/haproxy.c b/src/haproxy.c index b62f30534..030a97325 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1649,11 +1649,19 @@ static void init_args(int argc, char **argv) else if (*flag == 'd' && flag[1] == 'W') arg_mode |= MODE_ZERO_WARNING; else if (*flag == 'd' && flag[1] == 'M') { - mem_poison_byte = flag[2] ? strtol(flag + 2, NULL, 0) : 'P'; - if (mem_poison_byte >= 0) - pool_debugging |= POOL_DBG_POISON; - else - pool_debugging &= ~POOL_DBG_POISON; + int ret = pool_parse_debugging(flag + 2, &err_msg); + + if (ret <= -1) { + if (ret < -1) + ha_alert("-dM: %s\n", err_msg); + else + printf("%s\n", err_msg); + ha_free(&err_msg); + exit(ret < -1 ? EXIT_FAILURE : 0); + } else if (ret == 0) { + ha_warning("-dM: %s\n", err_msg); + ha_free(&err_msg); + } } else if (*flag == 'd' && flag[1] == 'r') global.tune.options |= GTUNE_RESOLVE_DONTFAIL; diff --git a/src/pool.c b/src/pool.c index 2cb37f345..4998f09b5 100644 --- a/src/pool.c +++ b/src/pool.c @@ -891,6 +891,34 @@ unsigned long pool_total_used() return used; } +/* This function parses a string made of a set of debugging features as + * specified after -dM on the command line, and will set pool_debugging + * accordingly. On success it returns a strictly positive value. It may zero + * with the first warning in , -1 with a help message in , or -2 with + * the first error in return the first error in . is undefined + * on success, and will be non-null and locally allocated on help/error/warning. + * The caller must free it. Warnings are used to report features that were not + * enabled at build time, and errors are used to report unknown features. + */ +int pool_parse_debugging(const char *str, char **err) +{ + char *end; + int v; + + + /* if it's empty or starts with a number, it's the mem poisonning byte */ + v = strtol(str, &end, 0); + if (!*end || *end == ',') { + mem_poison_byte = *str ? v : 'P'; + if (mem_poison_byte >= 0) + pool_debugging |= POOL_DBG_POISON; + else + pool_debugging &= ~POOL_DBG_POISON; + str = end; + } + return 1; +} + /* This function dumps memory usage information onto the stream interface's * read buffer. It returns 0 as long as it does not complete, non-zero upon * completion. No state is used.