btrfs-progs: build: add more debugging features
authorDavid Sterba <dsterba@suse.com>
Fri, 19 Aug 2016 14:06:41 +0000 (16:06 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 22 Aug 2016 14:44:22 +0000 (16:44 +0200)
Add options to show file and line or stack trace for error/warning
messages that use the common helpers. Possible to let any error stop
execution for ease of analysis and debugging.

Signed-off-by: David Sterba <dsterba@suse.com>
Makefile.in
utils.h

index ac6b353..9e0cb4c 100644 (file)
 #   V=1            verbose, print command lines (default: quiet)
 #   C=1            run checker before compilation (default checker: sparse)
 #   D=1            debugging build, turn off optimizations
+#   D=dflags       dtto, turn on additional debugging features:
+#                  verbose - print file:line along with error/warning messages
+#                  trace   - print trace before the error/warning messages
+#                  abort   - call abort() on first error (dumps core)
+#                  all     - shortcut for all of the above
 #   W=123          build with warnings (default: off)
 #   DEBUG_CFLAGS   additional compiler flags for debugging build
 #   EXTRA_CFLAGS   additional compiler flags
@@ -121,6 +126,24 @@ ifeq ("$(origin D)", "command line")
   DEBUG_CFLAGS_INTERNAL = $(DEBUG_CFLAGS_DEFAULT) $(DEBUG_CFLAGS)
 endif
 
+ifneq (,$(findstring verbose,$(D)))
+  DEBUG_CFLAGS_INTERNAL += -DDEBUG_VERBOSE_ERROR=1
+endif
+
+ifneq (,$(findstring trace,$(D)))
+  DEBUG_CFLAGS_INTERNAL += -DDEBUG_TRACE_ON_ERROR=1
+endif
+
+ifneq (,$(findstring abort,$(D)))
+  DEBUG_CFLAGS_INTERNAL += -DDEBUG_ABORT_ON_ERROR=1
+endif
+
+ifneq (,$(findstring all,$(D)))
+  DEBUG_CFLAGS_INTERNAL += -DDEBUG_VERBOSE_ERROR=1
+  DEBUG_CFLAGS_INTERNAL += -DDEBUG_TRACE_ON_ERROR=1
+  DEBUG_CFLAGS_INTERNAL += -DDEBUG_ABORT_ON_ERROR=1
+endif
+
 MAKEOPTS = --no-print-directory Q=$(Q)
 
 # build all by default
diff --git a/utils.h b/utils.h
index 58121ce..da23bfc 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -311,8 +311,61 @@ void clean_args_no_options_relaxed(int argc, char *argv[],
                const char * const *usagestr);
 int string_is_numerical(const char *str);
 
+#if DEBUG_VERBOSE_ERROR
+#define        PRINT_VERBOSE_ERROR     fprintf(stderr, "%s:%d:", __FILE__, __LINE__)
+#else
+#define PRINT_VERBOSE_ERROR
+#endif
+
+#if DEBUG_TRACE_ON_ERROR
+#define PRINT_TRACE_ON_ERROR   print_trace()
+#else
+#define PRINT_TRACE_ON_ERROR
+#endif
+
+#if DEBUG_ABORT_ON_ERROR
+#define DO_ABORT_ON_ERROR      abort()
+#else
+#define DO_ABORT_ON_ERROR
+#endif
+
+#define error(fmt, ...)                                                        \
+       do {                                                            \
+               PRINT_TRACE_ON_ERROR;                                   \
+               PRINT_VERBOSE_ERROR;                                    \
+               __error((fmt), ##__VA_ARGS__);                          \
+               DO_ABORT_ON_ERROR;                                      \
+       } while (0)
+
+#define error_on(cond, fmt, ...)                                       \
+       do {                                                            \
+               if ((cond))                                             \
+                       PRINT_TRACE_ON_ERROR;                           \
+               if ((cond))                                             \
+                       PRINT_VERBOSE_ERROR;                            \
+               __error_on((cond), (fmt), ##__VA_ARGS__);               \
+               if ((cond))                                             \
+                       DO_ABORT_ON_ERROR;                              \
+       } while (0)
+
+#define warning(fmt, ...)                                              \
+       do {                                                            \
+               PRINT_TRACE_ON_ERROR;                                   \
+               PRINT_VERBOSE_ERROR;                                    \
+               __warning((fmt), ##__VA_ARGS__);                        \
+       } while (0)
+
+#define warning_on(cond, fmt, ...)                                     \
+       do {                                                            \
+               if ((cond))                                             \
+                       PRINT_TRACE_ON_ERROR;                           \
+               if ((cond))                                             \
+                       PRINT_VERBOSE_ERROR;                            \
+               __warning_on((cond), (fmt), ##__VA_ARGS__);             \
+       } while (0)
+
 __attribute__ ((format (printf, 1, 2)))
-static inline void warning(const char *fmt, ...)
+static inline void __warning(const char *fmt, ...)
 {
        va_list args;
 
@@ -324,7 +377,7 @@ static inline void warning(const char *fmt, ...)
 }
 
 __attribute__ ((format (printf, 1, 2)))
-static inline void error(const char *fmt, ...)
+static inline void __error(const char *fmt, ...)
 {
        va_list args;
 
@@ -336,7 +389,7 @@ static inline void error(const char *fmt, ...)
 }
 
 __attribute__ ((format (printf, 2, 3)))
-static inline int warning_on(int condition, const char *fmt, ...)
+static inline int __warning_on(int condition, const char *fmt, ...)
 {
        va_list args;
 
@@ -353,7 +406,7 @@ static inline int warning_on(int condition, const char *fmt, ...)
 }
 
 __attribute__ ((format (printf, 2, 3)))
-static inline int error_on(int condition, const char *fmt, ...)
+static inline int __error_on(int condition, const char *fmt, ...)
 {
        va_list args;