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 // tokudb debug tracing for tokudb_debug declared in tokudb_sysvars.h/.cc
33 #define TOKUDB_DEBUG_INIT                   (1<<0)
34 #define TOKUDB_DEBUG_OPEN                   (1<<1)
35 #define TOKUDB_DEBUG_ENTER                  (1<<2)
36 #define TOKUDB_DEBUG_RETURN                 (1<<3)
37 #define TOKUDB_DEBUG_ERROR                  (1<<4)
38 #define TOKUDB_DEBUG_TXN                    (1<<5)
39 #define TOKUDB_DEBUG_AUTO_INCREMENT         (1<<6)
40 #define TOKUDB_DEBUG_INDEX_KEY              (1<<7)
41 #define TOKUDB_DEBUG_LOCK                   (1<<8)
42 #define TOKUDB_DEBUG_CHECK_KEY              (1<<9)
43 #define TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS   (1<<10)
44 #define TOKUDB_DEBUG_ALTER_TABLE            (1<<11)
45 #define TOKUDB_DEBUG_UPSERT                 (1<<12)
46 #define TOKUDB_DEBUG_CHECK                  (1<<13)
47 #define TOKUDB_DEBUG_ANALYZE                (1<<14)
48 #define TOKUDB_DEBUG_XA                     (1<<15)
49 #define TOKUDB_DEBUG_SHARE                  (1<<16)
50 
51 #define TOKUDB_TRACE(_fmt, ...) { \
52     fprintf(stderr, "%u %s:%u %s " _fmt "\n", tokudb::thread::my_tid(), \
53             __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
54 }
55 
56 #define TOKUDB_DEBUG_FLAGS(_flags) \
57     (tokudb::sysvars::debug & _flags)
58 
59 #define TOKUDB_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \
60     if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \
61         TOKUDB_TRACE(_fmt, ##__VA_ARGS__); \
62     } \
63 }
64 
65 #define TOKUDB_DBUG_ENTER(_fmt, ...) { \
66     if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER)) { \
67         TOKUDB_TRACE(_fmt, ##__VA_ARGS__);       \
68     } \
69 } \
70     DBUG_ENTER(__FUNCTION__);
71 
72 #define TOKUDB_DBUG_RETURN(r) { \
73     int rr = (r); \
74     if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \
75         (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \
76         TOKUDB_TRACE("return %d", rr); \
77     } \
78     DBUG_RETURN(rr); \
79 }
80 
81 #define TOKUDB_HANDLER_TRACE(_fmt, ...) \
82     fprintf(stderr, "%u %p %s:%u ha_tokudb::%s " _fmt "\n", \
83             tokudb::thread::my_tid(), this, __FILE__, __LINE__, \
84             __FUNCTION__, ##__VA_ARGS__);
85 
86 #define TOKUDB_HANDLER_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \
87     if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \
88         TOKUDB_HANDLER_TRACE(_fmt, ##__VA_ARGS__); \
89     } \
90 }
91 
92 
93 #define TOKUDB_HANDLER_DBUG_ENTER(_fmt, ...) { \
94     if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER)) { \
95         TOKUDB_HANDLER_TRACE(_fmt, ##__VA_ARGS__); \
96     } \
97 } \
98     DBUG_ENTER(__FUNCTION__);
99 
100 #define TOKUDB_HANDLER_DBUG_RETURN(r) { \
101     int rr = (r); \
102     if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \
103         (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \
104         TOKUDB_HANDLER_TRACE("return %d", rr); \
105     } \
106     DBUG_RETURN(rr); \
107 }
108 
109 #define TOKUDB_HANDLER_DBUG_RETURN_DOUBLE(r) { \
110     double rr = (r); \
111     if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \
112         TOKUDB_HANDLER_TRACE("return %f", rr); \
113     } \
114     DBUG_RETURN(rr); \
115 }
116 
117 #define TOKUDB_HANDLER_DBUG_RETURN_PTR(r) { \
118     if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \
119         TOKUDB_HANDLER_TRACE("return 0x%p", r); \
120     } \
121     DBUG_RETURN(r); \
122 }
123 
124 #define TOKUDB_HANDLER_DBUG_VOID_RETURN { \
125     if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \
126         TOKUDB_HANDLER_TRACE("return");       \
127     } \
128     DBUG_VOID_RETURN; \
129 }
130 
131 #define TOKUDB_SHARE_TRACE(_fmt, ...) \
132     fprintf(stderr, "%u %p %s:%u TOUDB_SHARE::%s " _fmt "\n", \
133             tokudb::thread::my_tid(), this, __FILE__, __LINE__, \
134             __FUNCTION__, ##__VA_ARGS__);
135 
136 #define TOKUDB_SHARE_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \
137     if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \
138         TOKUDB_SHARE_TRACE(_fmt, ##__VA_ARGS__); \
139     } \
140 }
141 
142 #define TOKUDB_SHARE_DBUG_ENTER(_fmt, ...) { \
143     if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER) || \
144         (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \
145         TOKUDB_SHARE_TRACE(_fmt, ##__VA_ARGS__); \
146     } \
147 } \
148     DBUG_ENTER(__FUNCTION__);
149 
150 #define TOKUDB_SHARE_DBUG_RETURN(r) { \
151     int rr = (r); \
152     if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \
153         (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE) || \
154         (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \
155         TOKUDB_SHARE_TRACE("return %d", rr); \
156     } \
157     DBUG_RETURN(rr); \
158 }
159 
160 #define TOKUDB_SHARE_DBUG_RETURN_DOUBLE(r) { \
161     double rr = (r); \
162     if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \
163         (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \
164         TOKUDB_SHARE_TRACE("return %f", rr); \
165     } \
166     DBUG_RETURN(rr); \
167 }
168 
169 #define TOKUDB_SHARE_DBUG_RETURN_PTR(r) { \
170     if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \
171         (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \
172         TOKUDB_SHARE_TRACE("return 0x%p", r); \
173     } \
174     DBUG_RETURN(r); \
175 }
176 
177 #define TOKUDB_SHARE_DBUG_VOID_RETURN() { \
178     if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \
179         (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \
180         TOKUDB_SHARE_TRACE("return");       \
181     } \
182     DBUG_VOID_RETURN; \
183 }
184 
185 
186 #define TOKUDB_DBUG_DUMP(s, p, len) \
187 { \
188     TOKUDB_TRACE("%s", s); \
189     uint i;                                                             \
190     for (i=0; i<len; i++) {                                             \
191         fprintf(stderr, "%2.2x", ((uchar*)p)[i]);                       \
192     }                                                                   \
193     fprintf(stderr, "\n");                                              \
194 }
195 
196 // The intention is for a failed handlerton assert to invoke a failed assert
197 // in the fractal tree layer, which dumps engine status to the error log.
198 void toku_hton_assert_fail(
199     const char* /*expr_as_string*/,
200     const char* /*fun*/,
201     const char* /*file*/,
202     int /*line*/,
203     int /*errno*/)
204     __attribute__((__visibility__("default")))
205      __attribute__((__noreturn__));
206 
207 #define assert_always(expr) ((expr) ? (void)0 : \
208     toku_hton_assert_fail(#expr, __FUNCTION__, __FILE__, __LINE__, errno))
209 
210 #undef assert
211 #define assert(expr) assert_always(expr)
212 
213 #ifdef TOKUDB_DEBUG
214     #define assert_debug(expr) ((expr) ? (void)0 : \
215         toku_hton_assert_fail(#expr, __FUNCTION__, __FILE__, __LINE__, errno))
216 #else
217     #define assert_debug(expr)       (void)0
218 #endif // TOKUDB_DEBUG
219 
220 #define assert_unreachable __builtin_unreachable
221 
222 #endif // _TOKUDB_DEBUG_H
223