LCOV - code coverage report
Current view: top level - wibmod/src/WIB1/BUException - ExceptionBase_stacktrace.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 53 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 3 0

            Line data    Source code
       1              : #include "wibmod/WIB1/BUException/ExceptionBase.hh"
       2              : 
       3              : // Error string for stack string allocation error
       4              : static const char stackError[] = "Stack allocation failed.\n";
       5              : 
       6              : const char*
       7            0 : BUException::exBase::StackTrace() const throw()
       8              : {
       9            0 :   if (stackBuffer == NULL)
      10            0 :     return stackError;
      11              :   return stackBuffer;
      12              : }
      13              : 
      14              : void
      15            0 : BUException::exBase::AppendStackLine(const char* line) throw()
      16              : {
      17              :   // Check for NULL line
      18            0 :   if (line == NULL)
      19              :     return;
      20              : 
      21              :   // get raw line size
      22            0 :   size_t lineSize = strlen(line);
      23            0 :   if (lineSize >= (stackSize - stackUsed))
      24              :     lineSize = stackSize - stackUsed;
      25              :   // copy string
      26            0 :   strncpy(stackBuffer + stackUsed, line, lineSize);
      27              :   // update size
      28            0 :   stackUsed += lineSize;
      29              :   // Add eol
      30            0 :   if ((stackSize - stackUsed) > 1) {
      31            0 :     stackBuffer[stackUsed] = '\n';
      32            0 :     stackUsed++;
      33              :   }
      34              :   // add null terminator (there is always room for one(unless NULL))
      35            0 :   if (stackBuffer != NULL) {
      36            0 :     stackBuffer[stackUsed] = '\0';
      37              :   }
      38              : }
      39              : 
      40              : void
      41            0 : BUException::exBase::GenerateStackTrace() throw()
      42              : {
      43              :   // Get the thread/process ID for this stack trace
      44            0 :   PID = syscall(SYS_gettid);
      45              : 
      46              :   // Get the stack trace (void *s)
      47            0 :   const size_t maxStackSize = 20;
      48            0 :   void* functionStack[maxStackSize];
      49            0 :   size_t stackSize;
      50              : 
      51              :   // Fill functionStack with void * pointers to return address of the corresponding stack frame
      52              :   // filed up to maxStackSize with most recent calls
      53            0 :   stackSize = backtrace(functionStack, maxStackSize);
      54              : 
      55              :   // Get the stack trace strings  (we have to free this)
      56            0 :   char** functionNames = backtrace_symbols(functionStack, stackSize);
      57            0 :   if (functionNames == NULL) {
      58            0 :     fprintf(stderr, "Error in exBase::GenerateStackTrace(). backtrace_symbols failed\n");
      59            0 :     return;
      60              :   }
      61              : 
      62              :   char* demangledName = NULL;
      63              :   // Start stack trace from 3 to skip the exception class's functions
      64            0 :   for (size_t iFunction = 3; iFunction < stackSize; iFunction++) {
      65              :     // based off of http://panthema.net/2008/0901-stacktrace-demangled/
      66              :     // Be paranoid about these pointers and make sure they are valid
      67            0 :     if (functionNames[iFunction] == NULL) {
      68            0 :       AppendStackLine("Unknown");
      69            0 :       continue;
      70              :     }
      71              : 
      72            0 :     char* mangledStart = NULL;
      73            0 :     char* offsetStart = NULL;
      74            0 :     char* offsetEnd = NULL;
      75              : 
      76              :     // Find mangled and offset start/ends
      77            0 :     char* bufferEnd = functionNames[iFunction] + strlen(functionNames[iFunction]);
      78            0 :     for (char* buffer = functionNames[iFunction]; buffer != bufferEnd; buffer++) {
      79              :       // Look for function's opening '('
      80            0 :       if (*buffer == '(')
      81              :         mangledStart = buffer;
      82              :       // Look for offset in function
      83            0 :       else if (*buffer == '+')
      84              :         offsetStart = buffer;
      85              :       // Look for closing ')', but only if we've found an opening one
      86            0 :       else if ((*buffer == ')') && (offsetStart != NULL)) {
      87              :         offsetEnd = buffer;
      88              :         break;
      89              :       }
      90              :     }
      91              : 
      92              :     // if the parsing makes sense
      93            0 :     if ((mangledStart != NULL) && (offsetStart != NULL) && (offsetEnd != NULL) && (mangledStart < offsetStart)) {
      94              :       // Make manglesStart point to the beginning of the name
      95            0 :       mangledStart++;
      96              :       // put in a null terminator at offsetStart to end the mangled name
      97            0 :       *offsetStart = '\0';
      98              : 
      99              :       // Make offset start point to the beginning of the offset
     100            0 :       offsetStart++;
     101              :       // put a null terminator at the end of the offset
     102            0 :       *offsetEnd = '\0';
     103              : 
     104              :       // demangle
     105            0 :       size_t demangledSize = 0;
     106            0 :       int demangledRet = 0;
     107            0 :       char* retName = abi::__cxa_demangle(mangledStart, demangledName, &demangledSize, &demangledRet);
     108              :       // Append demangled line
     109            0 :       if ((demangledRet == 0) && (retName != NULL)) {
     110              :         // copy possibly reallocated c-string
     111            0 :         demangledName = retName;
     112            0 :         AppendStackLine(demangledName);
     113              :       } else // if ther was an error, append the mangled name
     114              :       {
     115            0 :         AppendStackLine(mangledStart);
     116              :       }
     117            0 :     } else // Bad parse, just print the line
     118              :     {
     119            0 :       AppendStackLine(functionNames[iFunction]);
     120              :     }
     121              :   }
     122              : 
     123            0 :   if (demangledName != NULL)
     124            0 :     free(demangledName);
     125            0 :   free(functionNames);
     126              : }
        

Generated by: LCOV version 2.0-1