} while (0)
+/* This is called by _BUG_ON() and _BUG_ON_ONCE() to count and handle the event. */
+#define __BUG_ON(_cond, _file, _line, _type, _details, ...) { \
+ static struct debug_count __dbg_cnt_##_line HA_SECTION("dbg_cnt") \
+ __attribute__((__used__,__aligned__(sizeof(void*)))) = { \
+ .file = _file, \
+ .func = __func__, \
+ .line = _line, \
+ .type = _type, \
+ .desc = (sizeof("" #_cond) > 1) ? \
+ (sizeof("" __VA_ARGS__) > 1) ? \
+ "" #_cond "\x1e" __VA_ARGS__ : \
+ "" #_cond : \
+ "" __VA_ARGS__, \
+ .count = 0, \
+ }; \
+ HA_WEAK(__start_dbg_cnt); \
+ HA_WEAK(__stop_dbg_cnt); \
+ _HA_ATOMIC_INC(&__dbg_cnt_##_line.count); \
+ if (_type != DBG_BUG_ONCE || \
+ ({ static int __match_count_##_line; \
+ !_HA_ATOMIC_FETCH_ADD(&__match_count_##_line, 1); })) { \
+ const char *msg = \
+ (sizeof("" __VA_ARGS__) > 1) ? \
+ "\"" #_cond "\" matched at " _file ":" #_line "\x1e" __VA_ARGS__ : \
+ "\"" #_cond "\" matched at " _file ":" #_line; \
+ complain(_details, msg); \
+ if (_details & DBG_DET_FAT_FATL) \
+ ABORT_NOW(); \
+ else if (_details & DBG_DET_FAT_WARN) \
+ ha_backtrace_to_stderr(0); \
+ } \
+ }
+
/* Matrix for DEBUG_COUNTERS:
* 0 : only BUG_ON() and CHECK_IF() are reported (super rare)
* 1 : COUNT_GLITCH() are also reported (rare)
# define _COUNT_IF(cond, file, line, ...) DISGUISE(unlikely(cond) ? 1 : 0)
# define _COUNT_GLITCH(file, line, ...) do { } while (0)
+/* This is called by _BUG_ON() and _BUG_ON_ONCE() to handle the event. */
+#define __BUG_ON(cond, file, line, type, details, ...) { \
+ const char *msg; \
+ if (sizeof("" __VA_ARGS__) > 1) \
+ msg = "\"" #cond "\" matched at " file ":" #line "\x1e" __VA_ARGS__; \
+ else \
+ msg = "\"" #cond "\" matched at " file ":" #line; \
+ if (type != DBG_BUG_ONCE || \
+ ({ static int __match_count_##line; \
+ !_HA_ATOMIC_FETCH_ADD(&__match_count_##line, 1); })) { \
+ complain(details, msg); \
+ if (details & DBG_DET_FAT_FATL) \
+ ABORT_NOW(); \
+ else if (details & DBG_DET_FAT_WARN) \
+ ha_backtrace_to_stderr(0); \
+ } \
+ }
+
#endif /* USE_OBSOLETE_LINKER */
/* reports a glitch for current file and line, optionally with an explanation */
*/
#define _BUG_ON(cond, file, line, details, ...) \
(void)(unlikely(cond) ? ({ \
- __DBG_COUNT(cond, file, line, DBG_BUG, __VA_ARGS__); \
__BUG_ON(cond, file, line, DBG_BUG, details, __VA_ARGS__); \
1; /* let's return the true condition */ \
}) : 0)
-/* This is called by _BUG_ON() and _BUG_ON_ONCE() to handle the event. */
-#define __BUG_ON(cond, file, line, type, details, ...) { \
- const char *msg; \
- if (sizeof("" __VA_ARGS__) > 1) \
- msg = "\"" #cond "\" matched at " file ":" #line "\x1e" __VA_ARGS__; \
- else \
- msg = "\"" #cond "\" matched at " file ":" #line; \
- if (type != DBG_BUG_ONCE || \
- ({ static int __match_count_##line; \
- !_HA_ATOMIC_FETCH_ADD(&__match_count_##line, 1); })) { \
- complain(details, msg); \
- if (details & DBG_DET_FAT_FATL) \
- ABORT_NOW(); \
- else if (details & DBG_DET_FAT_WARN) \
- ha_backtrace_to_stderr(0); \
- } \
- }
-
/* 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
*/
#define _BUG_ON_ONCE(cond, file, line, details, ...) \
(void)(unlikely(cond) ? ({ \
- __DBG_COUNT(cond, file, line, DBG_BUG_ONCE, __VA_ARGS__); \
__BUG_ON(cond, file, line, DBG_BUG_ONCE, details, __VA_ARGS__); \
1; /* let's return the true condition */ \
}) : 0)