diff --git a/common/format-output.c b/common/format-output.c index f0ec81fe..c194a23c 100644 --- a/common/format-output.c +++ b/common/format-output.c @@ -56,15 +56,14 @@ static void fmt_indent2(int indent) static void fmt_error(struct format_ctx *fctx) { - printf("INTERNAL ERROR: formatting json: depth=%d\n", fctx->depth); + internal_error("formatting json: depth=%d", fctx->depth); exit(1); } static void fmt_inc_depth(struct format_ctx *fctx) { if (fctx->depth >= JSON_NESTING_LIMIT - 1) { - printf("INTERNAL ERROR: nesting too deep, limit %d\n", - JSON_NESTING_LIMIT); + internal_error("nesting too deep, limit %d", JSON_NESTING_LIMIT); exit(1); } fctx->depth++; @@ -73,7 +72,7 @@ static void fmt_inc_depth(struct format_ctx *fctx) static void fmt_dec_depth(struct format_ctx *fctx) { if (fctx->depth < 1) { - printf("INTERNAL ERROR: nesting below first level\n"); + internal_error("nesting below first level"); exit(1); } fctx->depth--; @@ -244,7 +243,7 @@ void fmt_print(struct format_ctx *fctx, const char* key, ...) row++; } if (!found) { - printf("INTERNAL ERROR: unknown key: %s\n", key); + internal_error("unknown key: %s", key); exit(1); } @@ -319,7 +318,7 @@ void fmt_print(struct format_ctx *fctx, const char* key, ...) printf("%s", pretty_size_mode(size, unit_mode)); } else { - printf("INTERNAL ERROR: unknown format %s\n", row->fmt); + internal_error("unknown format %s", row->fmt); } fmt_end_value(fctx, row); diff --git a/common/messages.c b/common/messages.c index bc616849..09716a40 100644 --- a/common/messages.c +++ b/common/messages.c @@ -77,6 +77,22 @@ int __btrfs_error_on(int condition, const char *fmt, ...) return 1; } +__attribute__ ((format (printf, 1, 2))) +void internal_error(const char *fmt, ...) +{ + va_list vargs; + + va_start(vargs, fmt); + fputs("INTERNAL ERROR: ", stderr); + vfprintf(stderr, fmt, vargs); + va_end(vargs); + fputc('\n', stderr); + +#ifndef BTRFS_DISABLE_BACKTRACE + print_trace(); +#endif +} + /* * Print a message according to the global verbosity level. * diff --git a/common/messages.h b/common/messages.h index c443bd55..729df140 100644 --- a/common/messages.h +++ b/common/messages.h @@ -100,6 +100,9 @@ int __btrfs_warning_on(int condition, const char *fmt, ...); __attribute__ ((format (printf, 2, 3))) int __btrfs_error_on(int condition, const char *fmt, ...); +__attribute__ ((format (printf, 1, 2))) +void internal_error(const char *fmt, ...); + /* * Level of messages that must be printed by default (in case the verbosity * options haven't been set by the user) due to backward compatibility reasons diff --git a/common/units.c b/common/units.c index eaeb7e2f..94cfa057 100644 --- a/common/units.c +++ b/common/units.c @@ -17,6 +17,7 @@ #include #include #include "common/units.h" +#include "common/messages.h" /* * Note: this function uses a static per-thread buffer. Do not call this @@ -77,8 +78,7 @@ int pretty_size_snprintf(u64 size, char *str, size_t str_size, unsigned unit_mod /* Unknown mode */ if (!base) { - fprintf(stderr, "INTERNAL ERROR: unknown unit base, mode %u\n", - unit_mode); + internal_error("unknown unit base, mode %u", unit_mode); assert(0); return -1; } @@ -134,8 +134,7 @@ int pretty_size_snprintf(u64 size, char *str, size_t str_size, unsigned unit_mod if (num_divs >= ARRAY_SIZE(unit_suffix_binary)) { str[0] = '\0'; - printf("INTERNAL ERROR: unsupported unit suffix, index %d\n", - num_divs); + internal_error("unsupported unit suffix, index %d", num_divs); assert(0); return -1; }