Home > Software design >  How to print stacktrace once an exception is thrown before the catch block (stack unwinding)
How to print stacktrace once an exception is thrown before the catch block (stack unwinding)

Time:11-17

Let's say we have the following code:

#include <exception>


void funcA() {
    funcB();
}

void funcB() {
    funcC();
}

void funcC() {
    funcD();
}

void funcD() {
    throw std::runtime_error("Exception!!"); //3
}

void funcE() {
    int * p;
    delete p; //4
}

int main (int argc, char **argv) {
    
    try {
        funcA(); //1
    } catch (std::exception exc) {
        std::cerr << exc.what() << endl; //2
        return EXIT_FAILURE;
    }
    
    return EXIT_SUCCESS;
}

I want to print the stack trace with the line number of the thrown exception in a multi-threaded efficient way.

I've been checking the last couple of days the solutions and approaches people are doing but unfortunately nothing was useful in my case. I can use for example the boost library boost::stacktrace::stacktrace() in //2 or any other library but the problem here is I have to catch the exception to do this and this approach is not efficient if your code has hundreds of nested functions. You can't just go over all of them and wrap each one with try-catch and handle them separately.

So basically what I need to do is if an exception is thrown at //3 I should be able to print the stack trace of the exception in `//2

I'm aware of the stack unwinding and how it works, but as far as I understand whenever your code reaches the catch block this means that the exception stack has been unwinded and you can't get it. Please correct me if I'm wrong!

Is there a way at least to add something similar to middleware before unwinding the exception stack? Or do I have to do it manually?

Edit:

Also, what would happen when I can funcE() is a memory access exception but this exception is never caught. Is there a way to catch such kind of exceptions or at least print its stack trace before the crash?

Note:

I'm running my code on Linux and macOS, C 11 with Silicon web framework. It's a big system so I'm trying to achieve some logging mechanism that can be used across the system.

CodePudding user response:

I'm posting this in case anyone came across the same question and wanted a quick useful answer.

I've ended up overriding the main C throw exception behavior using this gist

I've changed a few things in the __cxa_throw function to tackle my own issue and used boost::stacktrace to get a more human-readable stack trace.

  • Related