Lunchbox  1.15.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 > inline std::string className( const T& object )
75  { return demangleTypeID( typeid( object ).name( )); }
76 
78 template< class T > inline std::string className( const T* object )
79  { return className( *object ); }
80 
81 #ifdef _WIN32
82 # pragma warning( default: 4100 )
83 #endif
84 
94 template< class T > inline std::string format( const T* data, const size_t num )
95 {
96  std::ostringstream os;
97  os << num << " " << className( data ) << " @ " << std::hex
98  << (const void*)data << ": 0x";
99  for( size_t i = 0; i < num; ++i )
100  {
101  if( (i % 8) == 0 )
102  os << " " << std::endl;
103  os << ' ' << data[i];
104  }
105  return os.str();
106 }
107 
108 template<> inline std::string format( const uint8_t* data, const size_t num )
109 {
110  std::ostringstream os;
111  os << num << " bytes @ " << std::hex << (const void*)data << ": 0x";
112  os.precision( 2 );
113  for( size_t i = 0; i < num; ++i )
114  {
115  if( (i % 32) == 0 )
116  os << " " << std::endl;
117  else if( (i % 8) == 0 )
118  os << ' ';
119  os << ' ' << std::setw(2) << int( data[i] );
120  }
121  return os.str();
122 }
123 
124 template<> inline std::string format( const void* data, const size_t num )
125  { return format( reinterpret_cast< const uint8_t* >( data ), num ); }
126 
127 template< class T > inline std::string format( const std::vector< T >& data )
128  { return format< T >( &data[0], data.size( )); }
129 
130 } // namespace lunchbox
131 
132 #ifdef NDEBUG
133 # ifdef LB_RELEASE_ASSERT
134 # define LBASSERT(x) \
135  { \
136  if( !(x) ) \
137  LBERROR << "##### Assert: " << #x << " #####" << std::endl \
138  << lunchbox::forceFlush; \
139  lunchbox::checkHeap(); \
140  }
141 # define LBASSERTINFO(x, info) \
142  { \
143  if( !(x) ) \
144  LBERROR << "##### Assert: " << #x << " [" << info << "] #####" \
145  << std::endl << lunchbox::forceFlush; \
146  lunchbox::checkHeap(); \
147  }
148 # define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
149 # else
150 # define LBASSERT(x)
151 # define LBASSERTINFO(x, info)
152 # define LBCHECK(x) { x; }
153 # endif
154 
155 # define LBUNIMPLEMENTED { LBERROR << "Unimplemented code in " << __FILE__ \
156  << ":" << __LINE__ << std::endl \
157  << lunchbox::forceFlush; }
158 # define LBUNREACHABLE { LBERROR << "Unreachable code in " << __FILE__ \
159  << ":" << __LINE__ << std::endl \
160  << lunchbox::forceFlush; }
161 # define LBDONTCALL \
162  { LBERROR << "Code is not supposed to be called in this context" \
163  << std::endl << lunchbox::forceFlush; }
164 # define LBABORT( info ) { \
165  LBERROR << "##### Abort: " << info << " #####" << std::endl \
166  << lunchbox::forceFlush; }
167 
168 #else // NDEBUG
169 
170 # define LBASSERT(x) \
171  { \
172  if( !(x) ) \
173  { \
174  LBERROR << "Assert: " << #x << " "; \
175  lunchbox::abort(); \
176  } \
177  lunchbox::checkHeap(); \
178  }
179 # define LBASSERTINFO(x, info) \
180  { \
181  if( !(x) ) \
182  { \
183  LBERROR << "Assert: " << #x << " [" << info << "] "; \
184  lunchbox::abort(); \
185  } \
186  lunchbox::checkHeap(); \
187  }
188 
189 # define LBUNIMPLEMENTED \
190  { LBERROR << "Unimplemented code in " << __FILE__ << ":" << __LINE__ \
191  << " " << lunchbox::className( *this ); \
192  lunchbox::abort(); }
193 # define LBUNREACHABLE \
194  { LBERROR << "Unreachable code in " << __FILE__ << ":" << __LINE__ \
195  << " " << lunchbox::className( *this ); \
196  lunchbox::abort(); }
197 # define LBDONTCALL \
198  { LBERROR << "Code is not supposed to be called in this context, type " \
199  << lunchbox::className( *this ); \
200  lunchbox::abort(); }
201 
202 # define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
203 # define LBABORT( info ) { \
204  LBERROR << "Abort: " << info; \
205  lunchbox::abort(); }
206 #endif // NDEBUG
207 
208 #define LBSAFECAST( to, in ) static_cast< to >( in ); \
209  LBASSERT( in == 0 || dynamic_cast< to >( static_cast< to >( in )))
210 
211 #endif //LUNCHBOX_DEBUG_H
std::string className(const T &object)
Print the RTTI name of the given class.
Definition: debug.h:74
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:94
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:32
This file contains logging classes.