Lunchbox  1.17.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
debug.h
1 
2 /* Copyright (c) 2007-2012, Stefan Eilemann <eile@equalizergraphics.com>
3  * 2013, Daniel Nachbaur <danielnachbaur@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU Lesser General Public License version 2.1 as published
7  * by the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef LUNCHBOX_DEBUG_H
20 #define LUNCHBOX_DEBUG_H
21 
22 #include <lunchbox/defines.h>
23 #include <lunchbox/log.h>
24 
25 #include <typeinfo>
26 
27 // assertions
28 // #define LB_RELEASE_ASSERT
29 
30 namespace lunchbox
31 {
36 LUNCHBOX_API void abort(bool dumpThreads = false);
37 
42 LUNCHBOX_API void checkHeap();
43 
50 LUNCHBOX_API std::ostream& sysError(std::ostream& os);
51 
53 LUNCHBOX_API std::string sysError();
54 
63 LUNCHBOX_API std::string backtrace(const size_t skipFrames);
64 
66 LUNCHBOX_API std::ostream& backtrace(std::ostream& os);
67 
68 LUNCHBOX_API std::string demangleTypeID(const char* mangled);
69 
70 #ifdef _WIN32
71 #pragma warning(disable : 4100) // VS Bug
72 #endif
73 
74 template <class T>
75 inline std::string className(const T& object)
76 {
77  return demangleTypeID(typeid(object).name());
78 }
79 
81 template <class T>
82 inline std::string className(const T* object)
83 {
84  return className(*object);
85 }
86 
87 #ifdef _WIN32
88 #pragma warning(default : 4100)
89 #endif
90 
100 template <class T>
101 inline std::string format(const T* data, const size_t num)
102 {
103  std::ostringstream os;
104  os << num << " " << className(data) << " @ " << std::hex
105  << (const void*)data << ": 0x";
106  for (size_t i = 0; i < num; ++i)
107  {
108  if ((i % 8) == 0)
109  os << " " << std::endl;
110  os << ' ' << data[i];
111  }
112  return os.str();
113 }
114 
115 template <>
116 inline std::string format(const uint8_t* data, const size_t num)
117 {
118  std::ostringstream os;
119  os << num << " bytes @ " << std::hex << (const void*)data << ": 0x";
120  os.precision(2);
121  for (size_t i = 0; i < num; ++i)
122  {
123  if ((i % 32) == 0)
124  os << " " << std::endl;
125  else if ((i % 8) == 0)
126  os << ' ';
127  os << ' ' << std::setw(2) << int(data[i]);
128  }
129  return os.str();
130 }
131 
132 template <>
133 inline std::string format(const void* data, const size_t num)
134 {
135  return format(reinterpret_cast<const uint8_t*>(data), num);
136 }
137 
138 template <class T>
139 inline std::string format(const std::vector<T>& data)
140 {
141  return format<T>(&data[0], data.size());
142 }
143 
144 } // namespace lunchbox
145 
146 #ifdef NDEBUG
147 #ifdef LB_RELEASE_ASSERT
148 #define LBASSERT(x) \
149  { \
150  if (!(x)) \
151  LBERROR << "##### Assert: " << #x << " #####" << std::endl \
152  << lunchbox::forceFlush; \
153  lunchbox::checkHeap(); \
154  }
155 #define LBASSERTINFO(x, info) \
156  { \
157  if (!(x)) \
158  LBERROR << "##### Assert: " << #x << " [" << info << "] #####" \
159  << std::endl \
160  << lunchbox::forceFlush; \
161  lunchbox::checkHeap(); \
162  }
163 #define LBCHECK(x) \
164  { \
165  const bool eqOk = x; \
166  LBASSERTINFO(eqOk, #x) \
167  }
168 #else
169 #define LBASSERT(x)
170 #define LBASSERTINFO(x, info)
171 #define LBCHECK(x) \
172  { \
173  x; \
174  }
175 #endif
176 
177 #define LBUNIMPLEMENTED \
178  { \
179  LBERROR << "Unimplemented code in " << __FILE__ << ":" << __LINE__ \
180  << std::endl \
181  << lunchbox::forceFlush; \
182  }
183 #define LBUNREACHABLE \
184  { \
185  LBERROR << "Unreachable code in " << __FILE__ << ":" << __LINE__ \
186  << std::endl \
187  << lunchbox::forceFlush; \
188  }
189 #define LBDONTCALL \
190  { \
191  LBERROR << "Code is not supposed to be called in this context" \
192  << std::endl \
193  << lunchbox::forceFlush; \
194  }
195 #define LBABORT(info) \
196  { \
197  LBERROR << "##### Abort: " << info << " #####" << std::endl \
198  << lunchbox::forceFlush; \
199  }
200 
201 #else // NDEBUG
202 
203 #define LBASSERT(x) \
204  { \
205  if (!(x)) \
206  { \
207  LBERROR << "Assert: " << #x << " "; \
208  lunchbox::abort(); \
209  } \
210  lunchbox::checkHeap(); \
211  }
212 #define LBASSERTINFO(x, info) \
213  { \
214  if (!(x)) \
215  { \
216  LBERROR << "Assert: " << #x << " [" << info << "] "; \
217  lunchbox::abort(); \
218  } \
219  lunchbox::checkHeap(); \
220  }
221 
222 #define LBUNIMPLEMENTED \
223  { \
224  LBERROR << "Unimplemented code in " << __FILE__ << ":" << __LINE__ \
225  << " " << lunchbox::className(*this); \
226  lunchbox::abort(); \
227  }
228 #define LBUNREACHABLE \
229  { \
230  LBERROR << "Unreachable code in " << __FILE__ << ":" << __LINE__ \
231  << " " << lunchbox::className(*this); \
232  lunchbox::abort(); \
233  }
234 #define LBDONTCALL \
235  { \
236  LBERROR << "Code is not supposed to be called in this context, type " \
237  << lunchbox::className(*this); \
238  lunchbox::abort(); \
239  }
240 
241 #define LBCHECK(x) \
242  { \
243  const bool eqOk = x; \
244  LBASSERTINFO(eqOk, #x) \
245  }
246 #define LBABORT(info) \
247  { \
248  LBERROR << "Abort: " << info; \
249  lunchbox::abort(); \
250  }
251 #endif // NDEBUG
252 
253 #define LBSAFECAST(to, in) \
254  static_cast<to>(in); \
255  LBASSERT(in == 0 || dynamic_cast<to>(static_cast<to>(in)))
256 
257 #endif // LUNCHBOX_DEBUG_H
std::string className(const T &object)
Print the RTTI name of the given class.
Definition: debug.h:75
std::ostream & sysError(std::ostream &os)
Print a textual description of the current system error.
std::string format(const T *data, const size_t num)
Format the given array in a human-readable form.
Definition: debug.h:101
Includes compile-time defines of Lunchbox.
std::string backtrace(const size_t skipFrames)
Get the current call stack.
Abstraction layer and common utilities for multi-threaded programming.
Definition: algorithm.h:29
This file contains logging classes.