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