-
Notifications
You must be signed in to change notification settings - Fork 527
Description
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 elseWhen 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