| 1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
| 2 | // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: |
| 3 | /* -*- mode: C; c-basic-offset: 4 -*- */ |
| 4 | #ident "$Id$" |
| 5 | /*====== |
| 6 | This file is part of TokuDB |
| 7 | |
| 8 | |
| 9 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
| 10 | |
| 11 | TokuDBis is free software: you can redistribute it and/or modify |
| 12 | it under the terms of the GNU General Public License, version 2, |
| 13 | as published by the Free Software Foundation. |
| 14 | |
| 15 | TokuDB is distributed in the hope that it will be useful, |
| 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | GNU General Public License for more details. |
| 19 | |
| 20 | You should have received a copy of the GNU General Public License |
| 21 | along with TokuDB. If not, see <http://www.gnu.org/licenses/>. |
| 22 | |
| 23 | ======= */ |
| 24 | |
| 25 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
| 26 | |
| 27 | #ifndef _TOKUDB_DEBUG_H |
| 28 | #define _TOKUDB_DEBUG_H |
| 29 | |
| 30 | #include "hatoku_defines.h" |
| 31 | |
| 32 | #define TOKU_INCLUDE_BACKTRACE 0 |
| 33 | #if TOKU_INCLUDE_BACKTRACE |
| 34 | static void tokudb_backtrace(void); |
| 35 | #endif |
| 36 | |
| 37 | // tokudb debug tracing for tokudb_debug declared in tokudb_sysvars.h/.cc |
| 38 | #define TOKUDB_DEBUG_INIT (1<<0) |
| 39 | #define TOKUDB_DEBUG_OPEN (1<<1) |
| 40 | #define TOKUDB_DEBUG_ENTER (1<<2) |
| 41 | #define TOKUDB_DEBUG_RETURN (1<<3) |
| 42 | #define TOKUDB_DEBUG_ERROR (1<<4) |
| 43 | #define TOKUDB_DEBUG_TXN (1<<5) |
| 44 | #define TOKUDB_DEBUG_AUTO_INCREMENT (1<<6) |
| 45 | #define TOKUDB_DEBUG_INDEX_KEY (1<<7) |
| 46 | #define TOKUDB_DEBUG_LOCK (1<<8) |
| 47 | #define TOKUDB_DEBUG_CHECK_KEY (1<<9) |
| 48 | #define TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS (1<<10) |
| 49 | #define TOKUDB_DEBUG_ALTER_TABLE (1<<11) |
| 50 | #define TOKUDB_DEBUG_UPSERT (1<<12) |
| 51 | #define TOKUDB_DEBUG_CHECK (1<<13) |
| 52 | #define TOKUDB_DEBUG_ANALYZE (1<<14) |
| 53 | #define TOKUDB_DEBUG_XA (1<<15) |
| 54 | #define TOKUDB_DEBUG_SHARE (1<<16) |
| 55 | |
| 56 | #define TOKUDB_TRACE(_fmt, ...) { \ |
| 57 | fprintf(stderr, "%u %s:%u %s " _fmt "\n", tokudb::thread::my_tid(), \ |
| 58 | __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ |
| 59 | } |
| 60 | |
| 61 | #define TOKUDB_DEBUG_FLAGS(_flags) \ |
| 62 | (tokudb::sysvars::debug & _flags) |
| 63 | |
| 64 | #define TOKUDB_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \ |
| 65 | if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \ |
| 66 | TOKUDB_TRACE(_fmt, ##__VA_ARGS__); \ |
| 67 | } \ |
| 68 | } |
| 69 | |
| 70 | #define TOKUDB_DBUG_ENTER(_fmt, ...) { \ |
| 71 | if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER)) { \ |
| 72 | TOKUDB_TRACE(_fmt, ##__VA_ARGS__); \ |
| 73 | } \ |
| 74 | } \ |
| 75 | DBUG_ENTER(__FUNCTION__); |
| 76 | |
| 77 | #define TOKUDB_DBUG_RETURN(r) { \ |
| 78 | int rr = (r); \ |
| 79 | if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ |
| 80 | (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \ |
| 81 | TOKUDB_TRACE("return %d", rr); \ |
| 82 | } \ |
| 83 | DBUG_RETURN(rr); \ |
| 84 | } |
| 85 | |
| 86 | #define TOKUDB_HANDLER_TRACE(_fmt, ...) \ |
| 87 | fprintf(stderr, "%u %p %s:%u ha_tokudb::%s " _fmt "\n", \ |
| 88 | tokudb::thread::my_tid(), this, __FILE__, __LINE__, \ |
| 89 | __FUNCTION__, ##__VA_ARGS__); |
| 90 | |
| 91 | #define TOKUDB_HANDLER_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \ |
| 92 | if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \ |
| 93 | TOKUDB_HANDLER_TRACE(_fmt, ##__VA_ARGS__); \ |
| 94 | } \ |
| 95 | } |
| 96 | |
| 97 | |
| 98 | #define TOKUDB_HANDLER_DBUG_ENTER(_fmt, ...) { \ |
| 99 | if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER)) { \ |
| 100 | TOKUDB_HANDLER_TRACE(_fmt, ##__VA_ARGS__); \ |
| 101 | } \ |
| 102 | } \ |
| 103 | DBUG_ENTER(__FUNCTION__); |
| 104 | |
| 105 | #define TOKUDB_HANDLER_DBUG_RETURN(r) { \ |
| 106 | int rr = (r); \ |
| 107 | if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ |
| 108 | (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \ |
| 109 | TOKUDB_HANDLER_TRACE("return %d", rr); \ |
| 110 | } \ |
| 111 | DBUG_RETURN(rr); \ |
| 112 | } |
| 113 | |
| 114 | #define TOKUDB_HANDLER_DBUG_RETURN_DOUBLE(r) { \ |
| 115 | double rr = (r); \ |
| 116 | if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \ |
| 117 | TOKUDB_HANDLER_TRACE("return %f", rr); \ |
| 118 | } \ |
| 119 | DBUG_RETURN(rr); \ |
| 120 | } |
| 121 | |
| 122 | #define TOKUDB_HANDLER_DBUG_RETURN_PTR(r) { \ |
| 123 | if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \ |
| 124 | TOKUDB_HANDLER_TRACE("return 0x%p", r); \ |
| 125 | } \ |
| 126 | DBUG_RETURN(r); \ |
| 127 | } |
| 128 | |
| 129 | #define TOKUDB_HANDLER_DBUG_VOID_RETURN { \ |
| 130 | if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \ |
| 131 | TOKUDB_HANDLER_TRACE("return"); \ |
| 132 | } \ |
| 133 | DBUG_VOID_RETURN; \ |
| 134 | } |
| 135 | |
| 136 | #define TOKUDB_SHARE_TRACE(_fmt, ...) \ |
| 137 | fprintf(stderr, "%u %p %s:%u TOUDB_SHARE::%s " _fmt "\n", \ |
| 138 | tokudb::thread::my_tid(), this, __FILE__, __LINE__, \ |
| 139 | __FUNCTION__, ##__VA_ARGS__); |
| 140 | |
| 141 | #define TOKUDB_SHARE_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \ |
| 142 | if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \ |
| 143 | TOKUDB_SHARE_TRACE(_fmt, ##__VA_ARGS__); \ |
| 144 | } \ |
| 145 | } |
| 146 | |
| 147 | #define TOKUDB_SHARE_DBUG_ENTER(_fmt, ...) { \ |
| 148 | if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER) || \ |
| 149 | (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ |
| 150 | TOKUDB_SHARE_TRACE(_fmt, ##__VA_ARGS__); \ |
| 151 | } \ |
| 152 | } \ |
| 153 | DBUG_ENTER(__FUNCTION__); |
| 154 | |
| 155 | #define TOKUDB_SHARE_DBUG_RETURN(r) { \ |
| 156 | int rr = (r); \ |
| 157 | if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ |
| 158 | (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE) || \ |
| 159 | (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \ |
| 160 | TOKUDB_SHARE_TRACE("return %d", rr); \ |
| 161 | } \ |
| 162 | DBUG_RETURN(rr); \ |
| 163 | } |
| 164 | |
| 165 | #define TOKUDB_SHARE_DBUG_RETURN_DOUBLE(r) { \ |
| 166 | double rr = (r); \ |
| 167 | if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ |
| 168 | (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ |
| 169 | TOKUDB_SHARE_TRACE("return %f", rr); \ |
| 170 | } \ |
| 171 | DBUG_RETURN(rr); \ |
| 172 | } |
| 173 | |
| 174 | #define TOKUDB_SHARE_DBUG_RETURN_PTR(r) { \ |
| 175 | if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ |
| 176 | (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ |
| 177 | TOKUDB_SHARE_TRACE("return 0x%p", r); \ |
| 178 | } \ |
| 179 | DBUG_RETURN(r); \ |
| 180 | } |
| 181 | |
| 182 | #define TOKUDB_SHARE_DBUG_VOID_RETURN() { \ |
| 183 | if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ |
| 184 | (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ |
| 185 | TOKUDB_SHARE_TRACE("return"); \ |
| 186 | } \ |
| 187 | DBUG_VOID_RETURN; \ |
| 188 | } |
| 189 | |
| 190 | |
| 191 | #define TOKUDB_DBUG_DUMP(s, p, len) \ |
| 192 | { \ |
| 193 | TOKUDB_TRACE("%s", s); \ |
| 194 | uint i; \ |
| 195 | for (i=0; i<len; i++) { \ |
| 196 | fprintf(stderr, "%2.2x", ((uchar*)p)[i]); \ |
| 197 | } \ |
| 198 | fprintf(stderr, "\n"); \ |
| 199 | } |
| 200 | |
| 201 | // The intention is for a failed handlerton assert to invoke a failed assert |
| 202 | // in the fractal tree layer, which dumps engine status to the error log. |
| 203 | void toku_hton_assert_fail( |
| 204 | const char* /*expr_as_string*/, |
| 205 | const char* /*fun*/, |
| 206 | const char* /*file*/, |
| 207 | int /*line*/, |
| 208 | int /*errno*/) |
| 209 | __attribute__((__visibility__("default" ))) |
| 210 | __attribute__((__noreturn__)); |
| 211 | |
| 212 | #define assert_always(expr) ((expr) ? (void)0 : \ |
| 213 | toku_hton_assert_fail(#expr, __FUNCTION__, __FILE__, __LINE__, errno)) |
| 214 | |
| 215 | #undef assert |
| 216 | #define assert(expr) assert_always(expr) |
| 217 | |
| 218 | #ifdef TOKUDB_DEBUG |
| 219 | #define assert_debug(expr) ((expr) ? (void)0 : \ |
| 220 | toku_hton_assert_fail(#expr, __FUNCTION__, __FILE__, __LINE__, errno)) |
| 221 | #else |
| 222 | #define assert_debug(expr) (void)0 |
| 223 | #endif // TOKUDB_DEBUG |
| 224 | |
| 225 | #define assert_unreachable __builtin_unreachable |
| 226 | |
| 227 | #endif // _TOKUDB_DEBUG_H |
| 228 | |