]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Add custom debug printing for your asserts
authorRich Ercolani <214141+rincebrain@users.noreply.github.com>
Wed, 10 Apr 2024 20:30:25 +0000 (16:30 -0400)
committerGitHub <noreply@github.com>
Wed, 10 Apr 2024 20:30:25 +0000 (13:30 -0700)
Being able to print custom debug information on assert trip
seems useful.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
Closes #15792

include/os/freebsd/spl/sys/debug.h
include/os/linux/spl/sys/debug.h
lib/libspl/include/assert.h
module/zfs/arc.c

index 785fcf62dd1651ca6a4a233cc4bbe246529089c5..f041dde34fc88779ae3b313083c5ae3df76dd1e4 100644 (file)
 /*
  * Common DEBUG functionality.
  */
+#ifdef __FreeBSD__
+#include <linux/compiler.h>
+#endif
+
+#ifndef __printflike
+#define        __printflike(a, b)      __printf(a, b)
+#endif
+
+#ifndef __maybe_unused
+#define        __maybe_unused __attribute__((unused))
+#endif
+
+/*
+ * Without this, we see warnings from objtool during normal Linux builds when
+ * the kernel is built with CONFIG_STACK_VALIDATION=y:
+ *
+ * warning: objtool: tsd_create() falls through to next function __list_add()
+ * warning: objtool: .text: unexpected end of section
+ *
+ * Until the toolchain stops doing this, we must only define this attribute on
+ * spl_panic() when doing static analysis.
+ */
 #if defined(__COVERITY__) || defined(__clang_analyzer__)
 __attribute__((__noreturn__))
 #endif
 extern void spl_panic(const char *file, const char *func, int line,
-    const char *fmt, ...) __attribute__((__noreturn__));
+    const char *fmt, ...);
 extern void spl_dumpstack(void);
 
 static inline int
@@ -73,8 +95,10 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
 #ifndef expect
 #define        expect(expr, value) (__builtin_expect((expr), (value)))
 #endif
+#ifndef __linux__
 #define        likely(expr)   expect((expr) != 0, 1)
 #define        unlikely(expr) expect((expr) != 0, 0)
+#endif
 
 #define        PANIC(fmt, a...)                                                \
        spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
@@ -84,6 +108,12 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
            spl_assert("VERIFY(" #cond ") failed\n",                    \
            __FILE__, __FUNCTION__, __LINE__))
 
+#define        VERIFYF(cond, str, ...)         do {                            \
+               if (unlikely(!cond))                                    \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY(" #cond ") failed " str "\n", __VA_ARGS__);\
+       } while (0)
+
 #define        VERIFY3B(LEFT, OP, RIGHT)       do {                            \
                const boolean_t _verify3_left = (boolean_t)(LEFT);      \
                const boolean_t _verify3_right = (boolean_t)(RIGHT);    \
@@ -123,7 +153,7 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
                if (unlikely(!(_verify3_left OP _verify3_right)))       \
                    spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
                    "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
-                   "failed (%p " #OP " %p)\n",                         \
+                   "failed (%px " #OP " %px)\n",                       \
                    (void *)_verify3_left,                              \
                    (void *)_verify3_right);                            \
        } while (0)
@@ -142,10 +172,98 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
                if (unlikely(!(0 == _verify0_right)))                   \
                    spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
                    "VERIFY0P(" #RIGHT ") "                             \
-                   "failed (NULL == %p)\n",                            \
+                   "failed (NULL == %px)\n",                           \
                    (void *)_verify0_right);                            \
        } while (0)
 
+/*
+ * Note that you should not put any operations you want to always happen
+ * in the print section for ASSERTs unless you only want them to run on
+ * debug builds!
+ * e.g. ASSERT3UF(2, <, 3, "%s", foo(x)), foo(x) won't run on non-debug
+ * builds.
+ */
+
+#define        VERIFY3BF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const boolean_t _verify3_left = (boolean_t)(LEFT);      \
+               const boolean_t _verify3_right = (boolean_t)(RIGHT);    \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%d " #OP " %d) " STR "\n",                 \
+                   (boolean_t)(_verify3_left),                         \
+                   (boolean_t)(_verify3_right),                        \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
+#define        VERIFY3SF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const int64_t _verify3_left = (int64_t)(LEFT);          \
+               const int64_t _verify3_right = (int64_t)(RIGHT);        \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%lld " #OP " %lld) " STR "\n",             \
+                   (long long)(_verify3_left),                         \
+                   (long long)(_verify3_right),                        \
+                   __VA_ARGS);                                         \
+       } while (0)
+
+#define        VERIFY3UF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const uint64_t _verify3_left = (uint64_t)(LEFT);        \
+               const uint64_t _verify3_right = (uint64_t)(RIGHT);      \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%llu " #OP " %llu) " STR "\n",             \
+                   (unsigned long long)(_verify3_left),                \
+                   (unsigned long long)(_verify3_right),               \
+                   __VA_ARGS);                                         \
+       } while (0)
+
+#define        VERIFY3PF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const uintptr_t _verify3_left = (uintptr_t)(LEFT);      \
+               const uintptr_t _verify3_right = (uintptr_t)(RIGHT);    \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%px " #OP " %px) " STR "\n",               \
+                   (void *) (_verify3_left),                           \
+                   (void *) (_verify3_right),                          \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
+#define        VERIFY0PF(RIGHT, STR, ...)      do {                            \
+               const uintptr_t _verify3_left = (uintptr_t)(0);         \
+               const uintptr_t _verify3_right = (uintptr_t)(RIGHT);    \
+               if (unlikely(!(_verify3_left == _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY0(0 == " #RIGHT ") "                         \
+                   "failed (0 == %px) " STR "\n",                      \
+                   (long long) (_verify3_right),                       \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
+#define        VERIFY0F(RIGHT, STR, ...)       do {                            \
+               const int64_t _verify3_left = (int64_t)(0);             \
+               const int64_t _verify3_right = (int64_t)(RIGHT);        \
+               if (unlikely(!(_verify3_left == _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY0(0 == " #RIGHT ") "                         \
+                   "failed (0 == %lld) " STR "\n",                     \
+                   (long long) (_verify3_right),                       \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
+#define        VERIFY_IMPLY(A, B) \
+       ((void)(likely((!(A)) || (B)) ||                                \
+           spl_assert("(" #A ") implies (" #B ")",                     \
+           __FILE__, __FUNCTION__, __LINE__)))
+
+#define        VERIFY_EQUIV(A, B) \
+       ((void)(likely(!!(A) == !!(B)) ||                               \
+           spl_assert("(" #A ") is equivalent to (" #B ")",            \
+           __FILE__, __FUNCTION__, __LINE__)))
+
 /*
  * Debugging disabled (--disable-debug)
  */
@@ -162,6 +280,13 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
        ((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
 #define        ASSERT0(x)              ((void) sizeof ((uintptr_t)(x)))
 #define        ASSERT0P(x)             ((void) sizeof ((uintptr_t)(x)))
+#define        ASSERT3BF(x, y, z, str, ...)    ASSERT3B(x, y, z)
+#define        ASSERT3SF(x, y, z, str, ...)    ASSERT3S(x, y, z)
+#define        ASSERT3UF(x, y, z, str, ...)    ASSERT3U(x, y, z)
+#define        ASSERT3PF(x, y, z, str, ...)    ASSERT3P(x, y, z)
+#define        ASSERT0PF(x, str, ...)          ASSERT0P(x)
+#define        ASSERT0F(x, str, ...)           ASSERT0(x)
+#define        ASSERTF(x, str, ...)            ASSERT(x)
 #define        IMPLY(A, B)                                                     \
        ((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
 #define        EQUIV(A, B)             \
@@ -178,16 +303,16 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
 #define        ASSERT3P        VERIFY3P
 #define        ASSERT0         VERIFY0
 #define        ASSERT0P        VERIFY0P
+#define        ASSERT3BF       VERIFY3BF
+#define        ASSERT3SF       VERIFY3SF
+#define        ASSERT3UF       VERIFY3UF
+#define        ASSERT3PF       VERIFY3PF
+#define        ASSERT0PF       VERIFY0PF
+#define        ASSERT0F        VERIFY0F
+#define        ASSERTF         VERIFYF
 #define        ASSERT          VERIFY
-#define        IMPLY(A, B) \
-       ((void)(likely((!(A)) || (B)) ||                                \
-           spl_assert("(" #A ") implies (" #B ")",                     \
-           __FILE__, __FUNCTION__, __LINE__)))
-#define        EQUIV(A, B) \
-       ((void)(likely(!!(A) == !!(B)) ||                               \
-           spl_assert("(" #A ") is equivalent to (" #B ")",            \
-           __FILE__, __FUNCTION__, __LINE__)))
-
+#define        IMPLY           VERIFY_IMPLY
+#define        EQUIV           VERIFY_EQUIV
 
 #endif /* NDEBUG */
 
index 288193ad21c50973223a5883bdd3bd68641b25b9..f041dde34fc88779ae3b313083c5ae3df76dd1e4 100644 (file)
@@ -1,24 +1,29 @@
 /*
- *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
- *  Copyright (C) 2007 The Regents of the University of California.
- *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
- *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
- *  UCRL-CODE-235197
+ * Copyright (c) 2020 iXsystems, Inc.
+ * All rights reserved.
  *
- *  This file is part of the SPL, Solaris Porting Layer.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- *  The SPL is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  *
- *  The SPL is distributed in the hope that it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
+ * $FreeBSD$
  */
 
 /*
 #ifndef _SPL_DEBUG_H
 #define        _SPL_DEBUG_H
 
+
 /*
  * Common DEBUG functionality.
  */
+#ifdef __FreeBSD__
+#include <linux/compiler.h>
+#endif
+
+#ifndef __printflike
 #define        __printflike(a, b)      __printf(a, b)
+#endif
 
 #ifndef __maybe_unused
 #define        __maybe_unused __attribute__((unused))
@@ -80,6 +92,14 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
        return (0);
 }
 
+#ifndef expect
+#define        expect(expr, value) (__builtin_expect((expr), (value)))
+#endif
+#ifndef __linux__
+#define        likely(expr)   expect((expr) != 0, 1)
+#define        unlikely(expr) expect((expr) != 0, 0)
+#endif
+
 #define        PANIC(fmt, a...)                                                \
        spl_panic(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
 
@@ -88,6 +108,12 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
            spl_assert("VERIFY(" #cond ") failed\n",                    \
            __FILE__, __FUNCTION__, __LINE__))
 
+#define        VERIFYF(cond, str, ...)         do {                            \
+               if (unlikely(!cond))                                    \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY(" #cond ") failed " str "\n", __VA_ARGS__);\
+       } while (0)
+
 #define        VERIFY3B(LEFT, OP, RIGHT)       do {                            \
                const boolean_t _verify3_left = (boolean_t)(LEFT);      \
                const boolean_t _verify3_right = (boolean_t)(RIGHT);    \
@@ -150,6 +176,84 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
                    (void *)_verify0_right);                            \
        } while (0)
 
+/*
+ * Note that you should not put any operations you want to always happen
+ * in the print section for ASSERTs unless you only want them to run on
+ * debug builds!
+ * e.g. ASSERT3UF(2, <, 3, "%s", foo(x)), foo(x) won't run on non-debug
+ * builds.
+ */
+
+#define        VERIFY3BF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const boolean_t _verify3_left = (boolean_t)(LEFT);      \
+               const boolean_t _verify3_right = (boolean_t)(RIGHT);    \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%d " #OP " %d) " STR "\n",                 \
+                   (boolean_t)(_verify3_left),                         \
+                   (boolean_t)(_verify3_right),                        \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
+#define        VERIFY3SF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const int64_t _verify3_left = (int64_t)(LEFT);          \
+               const int64_t _verify3_right = (int64_t)(RIGHT);        \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%lld " #OP " %lld) " STR "\n",             \
+                   (long long)(_verify3_left),                         \
+                   (long long)(_verify3_right),                        \
+                   __VA_ARGS);                                         \
+       } while (0)
+
+#define        VERIFY3UF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const uint64_t _verify3_left = (uint64_t)(LEFT);        \
+               const uint64_t _verify3_right = (uint64_t)(RIGHT);      \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%llu " #OP " %llu) " STR "\n",             \
+                   (unsigned long long)(_verify3_left),                \
+                   (unsigned long long)(_verify3_right),               \
+                   __VA_ARGS);                                         \
+       } while (0)
+
+#define        VERIFY3PF(LEFT, OP, RIGHT, STR, ...)    do {                    \
+               const uintptr_t _verify3_left = (uintptr_t)(LEFT);      \
+               const uintptr_t _verify3_right = (uintptr_t)(RIGHT);    \
+               if (unlikely(!(_verify3_left OP _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY3(" #LEFT " "  #OP " "  #RIGHT ") "          \
+                   "failed (%px " #OP " %px) " STR "\n",               \
+                   (void *) (_verify3_left),                           \
+                   (void *) (_verify3_right),                          \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
+#define        VERIFY0PF(RIGHT, STR, ...)      do {                            \
+               const uintptr_t _verify3_left = (uintptr_t)(0);         \
+               const uintptr_t _verify3_right = (uintptr_t)(RIGHT);    \
+               if (unlikely(!(_verify3_left == _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY0(0 == " #RIGHT ") "                         \
+                   "failed (0 == %px) " STR "\n",                      \
+                   (long long) (_verify3_right),                       \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
+#define        VERIFY0F(RIGHT, STR, ...)       do {                            \
+               const int64_t _verify3_left = (int64_t)(0);             \
+               const int64_t _verify3_right = (int64_t)(RIGHT);        \
+               if (unlikely(!(_verify3_left == _verify3_right)))       \
+                   spl_panic(__FILE__, __FUNCTION__, __LINE__,         \
+                   "VERIFY0(0 == " #RIGHT ") "                         \
+                   "failed (0 == %lld) " STR "\n",                     \
+                   (long long) (_verify3_right),                       \
+                   __VA_ARGS__);                                       \
+       } while (0)
+
 #define        VERIFY_IMPLY(A, B) \
        ((void)(likely((!(A)) || (B)) ||                                \
            spl_assert("(" #A ") implies (" #B ")",                     \
@@ -176,6 +280,13 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
        ((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
 #define        ASSERT0(x)              ((void) sizeof ((uintptr_t)(x)))
 #define        ASSERT0P(x)             ((void) sizeof ((uintptr_t)(x)))
+#define        ASSERT3BF(x, y, z, str, ...)    ASSERT3B(x, y, z)
+#define        ASSERT3SF(x, y, z, str, ...)    ASSERT3S(x, y, z)
+#define        ASSERT3UF(x, y, z, str, ...)    ASSERT3U(x, y, z)
+#define        ASSERT3PF(x, y, z, str, ...)    ASSERT3P(x, y, z)
+#define        ASSERT0PF(x, str, ...)          ASSERT0P(x)
+#define        ASSERT0F(x, str, ...)           ASSERT0(x)
+#define        ASSERTF(x, str, ...)            ASSERT(x)
 #define        IMPLY(A, B)                                                     \
        ((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
 #define        EQUIV(A, B)             \
@@ -192,6 +303,13 @@ spl_assert(const char *buf, const char *file, const char *func, int line)
 #define        ASSERT3P        VERIFY3P
 #define        ASSERT0         VERIFY0
 #define        ASSERT0P        VERIFY0P
+#define        ASSERT3BF       VERIFY3BF
+#define        ASSERT3SF       VERIFY3SF
+#define        ASSERT3UF       VERIFY3UF
+#define        ASSERT3PF       VERIFY3PF
+#define        ASSERT0PF       VERIFY0PF
+#define        ASSERT0F        VERIFY0F
+#define        ASSERTF         VERIFYF
 #define        ASSERT          VERIFY
 #define        IMPLY           VERIFY_IMPLY
 #define        EQUIV           VERIFY_EQUIV
index 57f5719c1ac1a3b9a86deccc468495efb40869a9..155bbab3020ae276ba097138b96e9fd2197e5e5b 100644 (file)
@@ -70,6 +70,15 @@ libspl_assert(const char *buf, const char *file, const char *func, int line)
 #define        VERIFY(cond)                                                    \
        (void) ((!(cond)) &&                                            \
            libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
+
+#define        VERIFYF(cond, STR, ...)                                         \
+do {                                                                   \
+       if (!(cond))                                                    \
+               libspl_assertf(__FILE__, __FUNCTION__, __LINE__,        \
+                   "%s " STR, #cond,                                   \
+                   __VA_ARGS__);                                       \
+} while (0)
+
 #define        verify(cond)                                                    \
        (void) ((!(cond)) &&                                            \
            libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
@@ -132,6 +141,79 @@ do {                                                                       \
                    (void *)__left);                                    \
 } while (0)
 
+/*
+ * This is just here because cstyle gets upset about #LEFT
+ * on a newline.
+ */
+
+/* BEGIN CSTYLED */
+#define        VERIFY3BF(LEFT, OP, RIGHT, STR, ...)                            \
+do {                                                                   \
+       const boolean_t __left = (boolean_t)(LEFT);                     \
+       const boolean_t __right = (boolean_t)(RIGHT);                   \
+       if (!(__left OP __right))                                       \
+               libspl_assertf(__FILE__, __FUNCTION__, __LINE__,        \
+                   "%s %s %s (0x%llx %s 0x%llx) " STR,                 \
+                   #LEFT, #OP, #RIGHT,                                 \
+                   (u_longlong_t)__left, #OP, (u_longlong_t)__right,   \
+                   __VA_ARGS__);                                       \
+} while (0)
+
+#define        VERIFY3SF(LEFT, OP, RIGHT, STR, ...)                            \
+do {                                                                   \
+       const int64_t __left = (int64_t)(LEFT);                         \
+       const int64_t __right = (int64_t)(RIGHT);                       \
+       if (!(__left OP __right))                                       \
+               libspl_assertf(__FILE__, __FUNCTION__, __LINE__,        \
+                   "%s %s %s (0x%llx %s 0x%llx) " STR,                 \
+                   #LEFT, #OP, #RIGHT,                                 \
+                   (u_longlong_t)__left, #OP, (u_longlong_t)__right,   \
+                   __VA_ARGS__);                                       \
+} while (0)
+
+#define        VERIFY3UF(LEFT, OP, RIGHT, STR, ...)                            \
+do {                                                                   \
+       const uint64_t __left = (uint64_t)(LEFT);                       \
+       const uint64_t __right = (uint64_t)(RIGHT);                     \
+       if (!(__left OP __right))                                       \
+               libspl_assertf(__FILE__, __FUNCTION__, __LINE__,        \
+                   "%s %s %s (0x%llx %s 0x%llx) " STR,                 \
+                   #LEFT, #OP, #RIGHT,                                 \
+                   (u_longlong_t)__left, #OP, (u_longlong_t)__right,   \
+                   __VA_ARGS__);                                       \
+} while (0)
+
+#define        VERIFY3PF(LEFT, OP, RIGHT, STR, ...)                            \
+do {                                                                   \
+       const uintptr_t __left = (uintptr_t)(LEFT);                     \
+       const uintptr_t __right = (uintptr_t)(RIGHT);                   \
+       if (!(__left OP __right))                                       \
+               libspl_assertf(__FILE__, __FUNCTION__, __LINE__,        \
+                   "%s %s %s (0x%llx %s 0x%llx) " STR,                 \
+                   #LEFT, #OP, #RIGHT,                                 \
+                   (u_longlong_t)__left, #OP, (u_longlong_t)__right,   \
+                   __VA_ARGS__);                                       \
+} while (0)
+/* END CSTYLED */
+
+#define        VERIFY0F(LEFT, STR, ...)                                        \
+do {                                                                   \
+       const uint64_t __left = (uint64_t)(LEFT);                       \
+       if (!(__left == 0))                                             \
+               libspl_assertf(__FILE__, __FUNCTION__, __LINE__,        \
+                   "%s == 0 (0x%llx == 0) " STR, #LEFT,                \
+                   (u_longlong_t)__left, __VA_ARGS__);                 \
+} while (0)
+
+#define        VERIFY0PF(LEFT, STR, ...)                                       \
+do {                                                                   \
+       const uintptr_t __left = (uintptr_t)(LEFT);                     \
+       if (!(__left == 0))                                             \
+               libspl_assertf(__FILE__, __FUNCTION__, __LINE__,        \
+                   "%s == 0 (%p == 0) " STR, #LEFT,                    \
+                   (u_longlong_t)__left, __VA_ARGS__);                 \
+} while (0)
+
 #ifdef assert
 #undef assert
 #endif
@@ -147,7 +229,15 @@ do {                                                                       \
        ((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
 #define        ASSERT0(x)              ((void) sizeof ((uintptr_t)(x)))
 #define        ASSERT0P(x)             ((void) sizeof ((uintptr_t)(x)))
+#define        ASSERT3BF(x, y, z, str, ...)    ASSERT3B(x, y, z)
+#define        ASSERT3SF(x, y, z, str, ...)    ASSERT3S(x, y, z)
+#define        ASSERT3UF(x, y, z, str, ...)    ASSERT3U(x, y, z)
+#define        ASSERT3PF(x, y, z, str, ...)    ASSERT3P(x, y, z)
+#define        ASSERT0P(x)             ((void) sizeof ((uintptr_t)(x)))
+#define        ASSERT0PF(x, str, ...)          ASSERT0P(x)
+#define        ASSERT0F(x, str, ...)           ASSERT0(x)
 #define        ASSERT(x)               ((void) sizeof ((uintptr_t)(x)))
+#define        ASSERTF(x, str, ...)    ASSERT(x)
 #define        assert(x)               ((void) sizeof ((uintptr_t)(x)))
 #define        IMPLY(A, B)                                                     \
        ((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
@@ -160,7 +250,14 @@ do {                                                                       \
 #define        ASSERT3P        VERIFY3P
 #define        ASSERT0         VERIFY0
 #define        ASSERT0P        VERIFY0P
+#define        ASSERT3BF       VERIFY3BF
+#define        ASSERT3SF       VERIFY3SF
+#define        ASSERT3UF       VERIFY3UF
+#define        ASSERT3PF       VERIFY3PF
+#define        ASSERT0PF       VERIFY0PF
+#define        ASSERT0F        VERIFY0F
 #define        ASSERT          VERIFY
+#define        ASSERTF         VERIFYF
 #define        assert          VERIFY
 #define        IMPLY(A, B) \
        ((void)(((!(A)) || (B)) || \
index 16c95db10f47fa4760138c19ef1ce7b610018b3a..6954051b1d19c8b5521bbe929b16fbaa64c81a20 100644 (file)
@@ -1960,7 +1960,7 @@ arc_buf_untransform_in_place(arc_buf_t *buf)
        ASSERT(HDR_ENCRYPTED(hdr));
        ASSERT3U(hdr->b_crypt_hdr.b_ot, ==, DMU_OT_DNODE);
        ASSERT(HDR_EMPTY_OR_LOCKED(hdr));
-       ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL);
+       ASSERT3PF(hdr->b_l1hdr.b_pabd, !=, NULL, "hdr %px buf %px", hdr, buf);
 
        zio_crypt_copy_dnode_bonus(hdr->b_l1hdr.b_pabd, buf->b_data,
            arc_buf_size(buf));
@@ -2083,7 +2083,8 @@ arc_buf_fill(arc_buf_t *buf, spa_t *spa, const zbookmark_phys_t *zb,
                 * allocate a new data buffer for the buf.
                 */
                if (ARC_BUF_SHARED(buf)) {
-                       ASSERT(ARC_BUF_COMPRESSED(buf));
+                       ASSERTF(ARC_BUF_COMPRESSED(buf),
+                       "buf %p was uncompressed", buf);
 
                        /* We need to give the buf its own b_data */
                        buf->b_flags &= ~ARC_BUF_FLAG_SHARED;