Incorrect stack trace in kernel using uncaught std :: exception

There is my code:

#include <string> #include <tr1/functional> using namespace std; using namespace std::tr1; using namespace std::tr1::placeholders; class Event { public: typedef std::tr1::function<void()> Handler; void set(Handler h) { m_handler = h; } template<typename T, typename F> void set(T * obj, F memfn) { set(std::tr1::bind(memfn, obj)); } void operator()() { m_handler(); } static void fire(Event * event) throw () { (*event)(); } Handler m_handler; }; class BuggyHandler { public: BuggyHandler() { } BuggyHandler(Event * b) : bar(b) { bar->set(this, &BuggyHandler::HandleEvent); } void HandleEvent() { // throw std::length_error std::string().append(std::numeric_limits<size_t>::max(), '0'); } private: Event * bar; }; void get_correct_stacktrace() { Event bar; BuggyHandler handler(&bar); bar(); } void get_incorrect_stacktrace() { Event bar; BuggyHandler handler(&bar); Event::fire(&bar); } int main(int argc, char **argv) { int opt = atoi(argv[1]); if (opt) get_correct_stacktrace(); else get_incorrect_stacktrace(); } 

When i call / test 1, I can get the correct stack trace from the kernel:

 #0 0xffffe410 in __kernel_vsyscall () #1 0xf7d028d0 in raise () from /lib/libc.so.6 #2 0xf7d03ff3 in abort () from /lib/libc.so.6 #3 0xf7ede880 in __gnu_cxx::__verbose_terminate_handler () from /usr/lib/libstdc++.so.6 #4 0xf7edc2a5 in std::exception::what () from /usr/lib/libstdc++.so.6 #5 0xf7edc2e2 in std::terminate () from /usr/lib/libstdc++.so.6 #6 0xf7edc41a in __cxa_throw () from /usr/lib/libstdc++.so.6 #7 0xf7e73c6f in std::__throw_length_error () from /usr/lib/libstdc++.so.6 #8 0xf7eb9a17 in std::string::append () from /usr/lib/libstdc++.so.6 #9 0x08049b96 in BuggyHandler::HandleEvent (this=0xffc26c9c) at /home/liangxu/release/server_2.0/test/src/test.cc:54 #10 0x08049857 in get_correct_stacktrace () at /home/liangxu/release/server_2.0/test/src/test.cc:67 #11 0x080498e0 in main (argc=Cannot access memory at address 0x5ac6) at /home/liangxu/release/server_2.0/test/src/test.cc:81 

The throw exception is test.cc:54

When i call / test 0, I can get the wrong stack trace from the kernel:

 #0 0xffffe410 in __kernel_vsyscall () #1 0xf7d508d0 in raise () from /lib/libc.so.6 #2 0xf7d51ff3 in abort () from /lib/libc.so.6 #3 0xf7f2c880 in __gnu_cxx::__verbose_terminate_handler () from /usr/lib/libstdc++.so.6 #4 0xf7f2a2a5 in std::exception::what () from /usr/lib/libstdc++.so.6 #5 0xf7f2a2e2 in std::terminate () from /usr/lib/libstdc++.so.6 #6 0xf7f2a305 in std::exception::what () from /usr/lib/libstdc++.so.6 #7 0xf7f29d98 in __cxa_call_unexpected () from /usr/lib/libstdc++.so.6 #8 0x080497eb in get_incorrect_stacktrace () at /home/liangxu/release/server_2.0/test/src/test.cc:30 #9 0x080498f5 in main (argc=Cannot access memory at address 0x5adf) at /home/liangxu/release/server_2.0/test/src/test.cc:83 

There is no throw exception exception.

My compiler is "gcc (GCC) 4.1.2 20070115 (preview) (SUSE Linux)"

If compiled with "-fno-exceptions", both methods generate the correct stack trace.

What is the reason?

+4
source share
1 answer

Both stack traces are correct.

When you call Event::fire , an exception is HandleEvent in HandleEvent , and the stack is removed until it encounters a fire that has this exception specification.

If you do not know the actual behavior of the exception specifications, you can read about it here: http://www.gotw.ca/publications/mill22.htm

Basically, the throw () specification ensures that this method is not thrown if it fails if one of the calling calls invokes. When the stack erase attempts to exit this method, it checks the exception specification, sees that it does not match, and calls std::unexpected from the current non-proliferation location, so __cxa_call_unexpected () in your stack trace immediately after get_incorrect_stacktrace () .

In most cases, the use of exception specifications is useless in C ++, because a guarantee is provided due to a general program failure, something throws and should not.

+4
source

Source: https://habr.com/ru/post/1389399/


All Articles