No useful backtrace after uncaught exception in std::thread

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have a problem with uncaught exceptions in a std::thread. Normally when there's an uncaught exception, the backtrace in gdb will show where the actual exception was thrown. When using std::thread, the exception seems to be thrown from even before the thread's main function is called, making it almost impossible to find out what actually happened. An example should illustrace nicely:

   #include <stdexcept>
   #include <thread>
   void foo()
   {
        throw std::runtime_error("foo");
   }
   int
   main()
   {
        thread t(foo);
        t.join();
   }


Compile using "g++ -Wall -std=c++0x -g tmp.cpp", and run "gdb a.out":

   (gdb) r
   Starting program: /boris/home/tobias/a.out
   [Thread debugging using libthread_db enabled]
   Using host libthread_db library "/lib64/libthread_db.so.1".
   [New Thread 0x7ffff7dc1700 (LWP 2427)]
   terminate called after throwing an instance of 'std::runtime_error'
      what():  foo

   Program received signal SIGABRT, Aborted.
   [Switching to Thread 0x7ffff7dc1700 (LWP 2427)]
   0x00000034906362a5 in raise () from /lib64/libc.so.6
   Missing separate debuginfos, use: debuginfo-install
   boost-thread-1.47.0-3.fc16.x86_64 glibc-2.14.90-14.x86_64
   libgcc-4.6.2-1.fc16.x86_64 libstdc++-4.6.2-1.fc16.x86_64
   (gdb) bt
   #0  0x00000034906362a5 in raise () from /lib64/libc.so.6
   #1  0x0000003490637bbb in abort () from /lib64/libc.so.6
   #2  0x000000349aabbf8d in __gnu_cxx::__verbose_terminate_handler()
   () from /usr/lib64/libstdc++.so.6
   #3  0x000000349aaba146 in ?? () from /usr/lib64/libstdc++.so.6
   #4  0x000000349aaba173 in std::terminate() () from
   /usr/lib64/libstdc++.so.6
   #5  0x000000349aa70bdb in ?? () from /usr/lib64/libstdc++.so.6
   #6  0x0000003490a07d90 in start_thread () from /lib64/libpthread.so.0
   #7  0x00000034906eeddd in clone () from /lib64/libc.so.6


As you can see, foo() is not in the backtrace. Now, if I use boost::thread (1.47.0) instead:

   #include <stdexcept>
   #include <thread>
   #include <boost/thread.hpp>
   void foo()
   {
        throw std::runtime_error("foo");
   }
   int
   main()
   {
        boost::thread t(foo);
        t.join();
   }

The backtrace in gdb now looks like this:

   #0  0x00000034906362a5 in raise () from /lib64/libc.so.6
   #1  0x0000003490637bbb in abort () from /lib64/libc.so.6
   #2  0x000000349aabbf8d in __gnu_cxx::__verbose_terminate_handler()
   () from /usr/lib64/libstdc++.so.6
   #3  0x000000349aaba146 in ?? () from /usr/lib64/libstdc++.so.6
   #4  0x000000349aaba173 in std::terminate() () from
   /usr/lib64/libstdc++.so.6
   #5  0x000000349aaba26e in __cxa_throw () from /usr/lib64/libstdc++.so.6
   #6  0x0000000000403039 in foo () at tmp2.cpp:6
   #7  0x0000000000405b1f in boost::detail::thread_data<void
   (*)()>::run (this=0x60a0d0)
        at /usr/include/boost/thread/detail/thread.hpp:61
   #8  0x00007ffff7dd5bf9 in ?? () from
   /usr/lib64/libboost_thread-mt.so.1.47.0
   #9  0x0000003490a07d90 in start_thread () from /lib64/libpthread.so.0
   #10 0x00000034906eeddd in clone () from /lib64/libc.so.6


That's more like it. Is the std::thread behaviour a bug, or am I missing something? Though the C++11 standard seems to allow the stack to be unwound before std::terminate is called, it exceptionally unhelpful. I've search but not been able to find any explanation.

I've tested this using both gcc 4.6.2 and 4.5.1 on Linux x64_64.

/Tobias



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux