LCOV - code coverage report
Current view: top level - include - mexcept.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 32 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 3 0

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         mexception.hxx
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     Midas exception with stack trace
       7              : 
       8              : \********************************************************************/
       9              : 
      10              : #ifndef _MEXCEPT_HXX
      11              : #define _MEXCEPT_HXX
      12              : 
      13              : #include <string>
      14              : #include <iostream>
      15              : #include <sstream>
      16              : #include <stdexcept>
      17              : #include <execinfo.h>
      18              : #include <dlfcn.h>
      19              : #include <cxxabi.h>
      20              : 
      21              : /*------------------------------------------------------------------*/
      22              : 
      23              : // throw exception with full stack trace
      24              : #define mthrow(arg) (throw mexception(arg, true, __FILE__, __LINE__))
      25              : 
      26              : // throw exception with line number and file name
      27              : #define mthrow1(arg) (throw mexception(arg, false, __FILE__, __LINE__))
      28              : 
      29              : // throw exception without file and line number
      30              : #define mthrow2(arg) (throw mexception(arg, false, "", 0))
      31              : 
      32              : class mexception : public std::runtime_error  {
      33              :    std::string msg;
      34              : public:
      35            0 :    mexception(const std::string &arg, bool stack_trace, const char *file, int line) :
      36            0 :            std::runtime_error(arg) {
      37            0 :       std::stringstream trace_buf;
      38            0 :       if (file[0])
      39            0 :          trace_buf << file << ":" << line << ": " << arg;
      40              :       else
      41            0 :          trace_buf << arg;
      42              : 
      43            0 :       if (stack_trace) {
      44              :          // create strack trace and add it to message
      45            0 :          trace_buf << std::endl << "Stack trace:" << std::endl;
      46            0 :          void *callstack[128];
      47            0 :          char buf[1024];
      48            0 :          int n = backtrace(callstack, sizeof(callstack) / sizeof(callstack[0]));
      49            0 :          char **symbols = backtrace_symbols(callstack, n);
      50            0 :          for (int i = 1; i < n; i++) {
      51            0 :             Dl_info info;
      52            0 :             if (dladdr(callstack[i], &info)) {
      53            0 :                char *demangled = nullptr;
      54            0 :                int status = 0;
      55            0 :                demangled = abi::__cxa_demangle(info.dli_sname, nullptr, 0, &status);
      56            0 :                snprintf(buf, sizeof(buf), "%-3d 0x%018lX %s + %zd\n",
      57            0 :                         i, (long unsigned int) callstack[i],
      58            0 :                         status == 0 ? demangled : info.dli_sname,
      59            0 :                         (char *) callstack[i] - (char *) info.dli_saddr);
      60            0 :                free(demangled);
      61              :             } else {
      62            0 :                snprintf(buf, sizeof(buf), "%-3d 0x%018lX\n",
      63            0 :                         i, (long unsigned int) callstack[i]);
      64              :             }
      65            0 :             trace_buf << buf;
      66              :          }
      67            0 :          free(symbols);
      68              :       }
      69              : 
      70            0 :       msg = trace_buf.str();
      71            0 :    }
      72              : 
      73            0 :    ~mexception() throw() {}
      74              : 
      75            0 :    const char *what() const throw() {
      76            0 :       return msg.c_str();
      77              :    }
      78              : 
      79              :    friend std::ostream &operator<<(std::ostream &output, mexception &m) {
      80              :       output << m.what();
      81              :       return output;
      82              :    };
      83              : 
      84              :    mexception(const mexception &ex) noexcept : std::runtime_error(ex.msg),msg(ex.msg) {};
      85              : };
      86              : 
      87              : static_assert(std::is_nothrow_copy_constructible<mexception>::value,
      88              :               "mexception must be nothrow copy constructible");
      89              : 
      90              : #endif // _MEXCEPT_HXX
        

Generated by: LCOV version 2.0-1