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/*======
6This file is part of TokuDB
7
8
9Copyright (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
34static 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.
203void 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