]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Update kqueue FD removal assert to print errno
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 7 Feb 2018 13:44:28 +0000 (13:44 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 7 Feb 2018 13:44:28 +0000 (13:44 +0000)
src/include/debug.h
src/lib/util/debug.c
src/lib/util/event.c

index 1b97412a801046eae5cfe87a508943275d6cbb77..c10ae95212c56dbc3b23a38bfabc4cd44173d797 100644 (file)
@@ -72,7 +72,8 @@ int           fr_fault_setup(char const *cmd, char const *program);
 void           fr_fault_set_cb(fr_fault_cb_t func);
 void           fr_fault_set_log_fd(int fd);
 void           fr_fault_log(char const *msg, ...) CC_HINT(format (printf, 1, 2));
-bool           fr_cond_assert_fail(char const *file, int line, char const *expr);
+bool           fr_cond_assert_fail(char const *file, int line, char const *expr, char const *msg, ...)
+               CC_HINT(format (printf, 4, 5));
 
 /** Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x
  *
@@ -87,7 +88,24 @@ bool         fr_cond_assert_fail(char const *file, int line, char const *expr);
  *
  * @param _x expression to test (should evaluate to true)
  */
-#define                fr_cond_assert(_x) likely((bool)((_x) ? true : (fr_cond_assert_fail(__FILE__, __LINE__, #_x) && false)))
+#define                fr_cond_assert(_x) likely((bool)((_x) ? true : (fr_cond_assert_fail(__FILE__, __LINE__, #_x, NULL) && false)))
+
+/** Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x
+ *
+ * Should be wrapped in a condition, and if false, should cause function to return
+ * an error code.  This allows control to return to the caller if a precondition is
+ * not satisfied and we're not debugging.
+ *
+ * Example:
+ @verbatim
+   if (!fr_cond_assert_msg(request, "Bad stuff happened: %s", fr_syserror(errno)))) return -1
+ @endverbatim
+ *
+ * @param _x   expression to test (should evaluate to true)
+ * @param _fmt of message to log.
+ * @param ...  fmt arguments.
+ */
+#define                fr_cond_assert_msg(_x, _fmt, ...) likely((bool)((_x) ? true : (fr_cond_assert_fail(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__) && false)))
 
 void           NEVER_RETURNS _fr_exit(char const *file, int line, int status);
 #  define      fr_exit(_x) _fr_exit(__FILE__, __LINE__, (_x))
index 953a6b51e3a07615c1bc18aeb36659dbdaf75371..04bd37c8de16cdd429e3ce05789e80f41fd908b7 100644 (file)
@@ -1089,13 +1089,31 @@ void fr_fault_set_log_fd(int fd)
 
 /** A soft assertion which triggers the fault handler in debug builds
  *
- * @param file the assertion failed in.
- * @param line of the assertion in the file.
- * @param expr that was evaluated.
+ * @param[in] file     the assertion failed in.
+ * @param[in] line     of the assertion in the file.
+ * @param[in] expr     that was evaluated.
+ * @param[in] fmt      Message to print (may be NULL).
+ * @param[in] ...      Arguments for msg string.
  * @return the value of cond.
  */
-bool fr_cond_assert_fail(char const *file, int line, char const *expr)
+bool fr_cond_assert_fail(char const *file, int line, char const *expr, char const *msg, ...)
 {
+       if (msg) {
+               char str[256];          /* Decent compilers won't allocate this unless fmt is !NULL... */
+               va_list ap;
+
+               va_start(ap, msg);
+               (void)vsnprintf(str, sizeof(str), msg, ap);
+               va_end(ap);
+
+#ifndef NDEBUG
+               FR_FAULT_LOG("ASSERT FAILED %s[%u]: %s: %s", file, line, expr, str);
+               fr_fault(SIGABRT);
+#else
+               FR_FAULT_LOG("ASSERT WOULD FAIL %s[%u]: %s: %s", file, line, expr, str);
+#endif
+       }
+
 #ifndef NDEBUG
        FR_FAULT_LOG("ASSERT FAILED %s[%u]: %s", file, line, expr);
        fr_fault(SIGABRT);
index 9aaf4898119b38dd485592dbf0f27ab274086c6d..62158993b1831162259080df6cd19a4bbec652c9 100644 (file)
@@ -626,7 +626,8 @@ static int fr_event_fd_delete_internal(fr_event_fd_t *ef)
                 *      If this fails, assert on debug builds, but ignore it at run-time.
                 */
                if (kevent(el->kq, evset, count, NULL, 0, NULL) < 0) {
-                       (void) fr_cond_assert("FD was closed without being removed from the KQ" == NULL);
+                       (void) fr_cond_assert_msg(false, "FD was closed without being removed from the KQ: %s",
+                                                 fr_syserror(errno));
                }
        }