LCOV - code coverage report
Current view: top level - lunchbox - debug.h (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 2 4 50.0 %
Date: 2014-08-05 Functions: 5 21 23.8 %

          Line data    Source code
       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             : {
      32             : /**
      33             :  * @internal
      34             :  * Used to trap into an infinite loop to allow debugging of assertions
      35             :  */
      36             : LUNCHBOX_API void abort();
      37             : 
      38             : /**
      39             :  * @internal
      40             :  * Check the consistency of the heap and abort on error (Win32 only).
      41             :  */
      42             : LUNCHBOX_API void checkHeap();
      43             : 
      44             : /**
      45             :  * Print a textual description of the current system error.
      46             :  *
      47             :  * The current system error is OS-specific, e.g., errno or GetLastError().
      48             :  * @version 1.0
      49             :  */
      50             : LUNCHBOX_API std::ostream& sysError( std::ostream& os );
      51             : 
      52             : /** @return a textual description of the current system error. @version 1.9.1 */
      53             : LUNCHBOX_API std::string sysError();
      54             : 
      55             : /**
      56             :  * Get the current call stack.
      57             :  *
      58             :  * May not be implemented on all platforms.
      59             :  *
      60             :  * @param skipFrames the number of most recent stack frames to ignore.
      61             :  * @version 1.9.1
      62             :  */
      63             : LUNCHBOX_API std::string backtrace( const size_t skipFrames );
      64             : 
      65             : /** Print the current call stack. @version 1.0 */
      66             : LUNCHBOX_API std::ostream& backtrace( std::ostream& os );
      67             : 
      68             : LUNCHBOX_API std::string demangleTypeID( const char* mangled ); //!< @internal
      69             : 
      70             : #ifdef _WIN32
      71             : #  pragma warning( disable: 4100 ) // VS Bug
      72             : #endif
      73             : /** Print the RTTI name of the given class. @version 1.0 */
      74           0 : template< class T > inline std::string className( const T* object )
      75           0 :     { return demangleTypeID( typeid( *object ).name( )); }
      76             : 
      77             : /** Print the RTTI name of the given class. @version 1.0 */
      78        3540 : template< class T > inline std::string className( const T& object )
      79        3540 :     { return demangleTypeID( typeid( object ).name( )); }
      80             : #ifdef _WIN32
      81             : #  pragma warning( default: 4100 )
      82             : #endif
      83             : 
      84             : /**
      85             :  * Format the given array in a human-readable form.
      86             :  * Depending on the data type, a different formatting may be used.
      87             :  *
      88             :  * @param data The pointer to the data to print.
      89             :  * @param num The number of elements of T to print, for T==void the number of
      90             :  *            bytes.
      91             :  * @version 1.9.1
      92             :  */
      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             : } // namespace lunchbox
     127             : 
     128             : #ifdef NDEBUG
     129             : #  ifdef LB_RELEASE_ASSERT
     130             : #    define LBASSERT(x)                                                 \
     131             :     {                                                                   \
     132             :         if( !(x) )                                                      \
     133             :             LBERROR << "##### Assert: " << #x << " #####" << std::endl  \
     134             :                     << lunchbox::forceFlush;                            \
     135             :         lunchbox::checkHeap();                                          \
     136             :     }
     137             : #    define LBASSERTINFO(x, info)                                       \
     138             :     {                                                                   \
     139             :         if( !(x) )                                                      \
     140             :             LBERROR << "##### Assert: " << #x << " [" << info << "] #####" \
     141             :                     << std::endl << lunchbox::forceFlush;               \
     142             :         lunchbox::checkHeap();                                          \
     143             :     }
     144             : #    define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
     145             : #  else
     146             : #    define LBASSERT(x)
     147             : #    define LBASSERTINFO(x, info)
     148             : #    define LBCHECK(x) { x; }
     149             : #  endif
     150             : 
     151             : #  define LBUNIMPLEMENTED { LBERROR << "Unimplemented code" << std::endl \
     152             :                                     << lunchbox::forceFlush; }
     153             : #  define LBUNREACHABLE   { LBERROR << "Unreachable code" << std::endl  \
     154             :                                     << lunchbox::forceFlush; }
     155             : #  define LBDONTCALL                                                    \
     156             :     { LBERROR << "Code is not supposed to be called in this context"    \
     157             :               << std::endl << lunchbox::forceFlush; }
     158             : #  define LBABORT( info ) {                                         \
     159             :         LBERROR << "##### Abort: " << info << " #####" << std::endl \
     160             :                 << lunchbox::forceFlush; }
     161             : 
     162             : #else // NDEBUG
     163             : 
     164             : #  define LBASSERT(x)                                                   \
     165             :     {                                                                   \
     166             :         if( !(x) )                                                      \
     167             :         {                                                               \
     168             :             LBERROR << "Assert: " << #x << " ";                         \
     169             :             lunchbox::abort();                                          \
     170             :         }                                                               \
     171             :         lunchbox::checkHeap();                                          \
     172             :     }
     173             : #  define LBASSERTINFO(x, info)                                         \
     174             :     {                                                                   \
     175             :         if( !(x) )                                                      \
     176             :         {                                                               \
     177             :             LBERROR << "Assert: " << #x << " [" << info << "] ";        \
     178             :             lunchbox::abort();                                          \
     179             :         }                                                               \
     180             :         lunchbox::checkHeap();                                          \
     181             :     }
     182             : 
     183             : #  define LBUNIMPLEMENTED                                               \
     184             :     { LBERROR << "Unimplemented code in " << lunchbox::className( this ) \
     185             :               << " ";                                                   \
     186             :         lunchbox::abort(); }
     187             : #  define LBUNREACHABLE                                                 \
     188             :     { LBERROR << "Unreachable code in " << lunchbox::className( this )  \
     189             :               << " ";                                                   \
     190             :         lunchbox::abort(); }
     191             : #  define LBDONTCALL                                                    \
     192             :     { LBERROR << "Code is not supposed to be called in this context, type " \
     193             :               << lunchbox::className( this ) << " " ;                   \
     194             :         lunchbox::abort(); }
     195             : 
     196             : #  define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
     197             : #  define LBABORT( info ) {                                             \
     198             :         LBERROR << "Abort: " << info;                                   \
     199             :         lunchbox::abort(); }
     200             : #endif // NDEBUG
     201             : 
     202             : #define LBSAFECAST( to, in ) static_cast< to >( in );   \
     203             :     LBASSERT( in == 0 || dynamic_cast< to >( static_cast< to >( in )))
     204             : 
     205             : #endif //LUNCHBOX_DEBUG_H

Generated by: LCOV version 1.10