LCOV - code coverage report
Current view: top level - lunchbox - debug.h (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 2 4 50.0 %
Date: 2018-10-03 05:33:11 Functions: 2 15 13.3 %

          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(bool dumpThreads = false);
      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             : template <class T>
      75        1663 : inline std::string className(const T& object)
      76             : {
      77        1663 :     return demangleTypeID(typeid(object).name());
      78             : }
      79             : 
      80             : /** Print the RTTI name of the given class. @version 1.0 */
      81             : template <class T>
      82           0 : inline std::string className(const T* object)
      83             : {
      84           0 :     return className(*object);
      85             : }
      86             : 
      87             : #ifdef _WIN32
      88             : #pragma warning(default : 4100)
      89             : #endif
      90             : 
      91             : /**
      92             :  * Format the given array in a human-readable form.
      93             :  * Depending on the data type, a different formatting may be used.
      94             :  *
      95             :  * @param data The pointer to the data to print.
      96             :  * @param num The number of elements of T to print, for T==void the number of
      97             :  *            bytes.
      98             :  * @version 1.9.1
      99             :  */
     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

Generated by: LCOV version 1.11