Skip to content

Can print stack trace in catch? #346

@K-KaUI

Description

@K-KaUI

Hi,
In a try block, several functions are called (which may come from third-party libraries). To ensure the system runs properly, exceptions thrown by these functions need to be caught. When an exception is caught, the call stack should be printed to help with troubleshooting, just like in the following Python example.
I understand that due to the stack unwinding issue in the C++ exception mechanism, it seems difficult to implement something similar to Python or other languages where the exception stack is printed in the catch block. Does backward-cpp support this feature? Or is there another way to achieve this?

import traceback

def do_something():
    raise Exception("throw exception from third-party library")

def test1():
    print("test1 ok")

def test2():
    do_something()

def test3():
    print("test3 ok")

if __name__ == '__main__':
    try:
        test1()
        test2()
        test3()
    except Exception as e:
        print(e)
        traceback.print_exc()
    print("do something else")
 
python test_exception.py 
test1 ok
throw exception from third-party library
Traceback (most recent call last):
  File "test_exception.py", line 18, in <module>
    test2()
  File "test_exception.py", line 10, in test2
    do_something()
  File "test_exception.py", line 4, in do_something
    raise Exception("throw exception from third-party library")
Exception: throw exception from third-party library
do something else

When using backward-cpp without exception handling, the program crashes and correctly prints the stack trace. However, when an exception is caught, it does nothing and does not print the stack trace.

#define BACKWARD_HAS_BFD 1
#include <iostream>
#include <exception>
#include <stdexcept>
#include "backward.hpp"
backward::SignalHandling sh{};
void do_something() {
    throw std::runtime_error("throw exception from third-party library");
}
void test1() {
    std::cout << "test1 ok" << std::endl;
}
void test2() {
    do_something();
}
void test3() {
    std::cout << "test3 ok" << std::endl;
}
int main() {
    // try {
        test1();
        test2();
        test3();
    // } catch (const std::exception& e) {
    //     std::cout << e.what() << std::endl;
    //     std::cout << "Exception caught: " << e.what() << std::endl;
    // }
    std::cout << "do something else" << std::endl;
    return 0;
}

./test_exception
test1 ok
terminate called after throwing an instance of 'std::runtime_error'
  what():  throw exception from third-party library
Stack trace (most recent call last):
#10   Object "", at 0xffffffffffffffff, in 
#9    Object "build/test_exception", at 0x55e45ba55fcd, in _start
BFD: DWARF error: section .debug_info is larger than its filesize! (0x93f189 vs 0x531098)
#8    Object "/lib/x86_64-linux-gnu/libc.so.6", at 0x7f40ba673082, in __libc_start_main
#7  | Source "test/test_exception.cpp", line 22, in main
    |    20:     // try {
    |    21:         test1();
    | >  22:         test2();
    |    23:         test3();
    |    24:     // } catch (const std::exception& e) {
      Source "test/test_exception.cpp", line 14, in test2() [0x55e45ba55e1d]
         11:     std::cout << "test1 ok" << std::endl;
         12: }
         13: void test2() {
      >  14:     do_something();
         15: }
         16: void test3() {
         17:     std::cout << "test3 ok" << std::endl;
#6    Source "test/test_exception.cpp", line 8, in do_something() [0x55e45ba560e7]
          5: #include "backward.hpp"
          6: backward::SignalHandling sh{};
          7: void do_something() {
      >   8:     throw std::runtime_error("throw exception from third-party library");
          9: }
         10: void test1() {
         11:     std::cout << "test1 ok" << std::endl;
#5    Object "/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7f40baa55698, in __cxa_throw
#4    Object "/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7f40baa553e6, in std::terminate()
#3    Object "/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7f40baa5537b, in std::rethrow_exception(std::__exception_ptr::exception_ptr)
#2    Object "/lib/x86_64-linux-gnu/libstdc++.so.6", at 0x7f40baa498d0, in __cxa_throw_bad_array_new_length
#1    Object "/lib/x86_64-linux-gnu/libc.so.6", at 0x7f40ba671858, in abort
#0    Object "/lib/x86_64-linux-gnu/libc.so.6", at 0x7f40ba69200b, in gsignal
Aborted (Signal sent by tkill() 168610 1000)
Aborted (core dumped)
#define BACKWARD_HAS_BFD 1
#include <iostream>
#include <exception>
#include <stdexcept>
#include "backward.hpp"
backward::SignalHandling sh{};
void do_something() {
    throw std::runtime_error("throw exception from third-party library");
}
void test1() {
    std::cout << "test1 ok" << std::endl;
}
void test2() {
    do_something();
}
void test3() {
    std::cout << "test3 ok" << std::endl;
}
int main() {
    try {
        test1();
        test2();
        test3();
    } catch (const std::exception& e) {
        std::cout << e.what() << std::endl;
        std::cout << "Exception caught: " << e.what() << std::endl;
    }
    std::cout << "do something else" << std::endl;
    return 0;
}

./test_exception
test1 ok
throw exception from third-party library
Exception caught: throw exception from third-party library
do something else

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions