在c++里,如果在Thread中有未捕获的异常,那么gcc会主动catch该异常,从而导致函数栈中无有用的信息。
下面是一个例子
#include <stdexcept>
#include <thread>
void foo()
{
throw std::runtime_error("foo");
}
void subroutine() {
std::thread t(foo);
t.join();
}
int main()
{
std::thread t(subroutine);
t.join();
}
使用编译命令
g++ -Wall -std=c++0x -g tmp.cpp
然后使用gdb执行
gdb a.out
(gdb) r
Using host libthread_db library "/lib/libthread_db.so.1".
[New Thread 0x7ffff7dc1700 (LWP 2427)]
terminate called after throwing an instance of 'std::runtime_error'
what(): foo
运行bt调出函数栈信息,发现没有有效的内容
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff7dc1700 (LWP 2427)]
0x00000034906362a5 in raise () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install
boost-thread-1.47.0-3.fc16.x86_ glibc-2.14.90-14.x86_
libgcc-4.6.2-1.fc16.x86_ libstdc++-4.6.2-1.fc16.x86_
(gdb) bt
() from /usr/lib/libstdc++.so.6
/usr/lib/libstdc++.so.6
解决方案
#include <stdexcept>
#include <thread>
void foo()
{
throw std::runtime_error("foo");
}
void subroutine() {
boost::thread t(foo);
t.join();
}
int main()
{
boost::thread t(subroutine);
t.join();
}
- 改用pthread
#include <stdexcept>
void *foo(void *)
{
throw std::runtime_error("foo");
}
void *subroutine(void *a) {
pthread_t thread_id;
pthread_create(&thread_id, NULL, foo, NULL);
pthread_join(thread_id,NULL);
return NULL;
}
int main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, subroutine, NULL);
pthread_join(thread_id,NULL);
return 0;
}
这时的函数栈可以显示到对应的crash函数了
from /lib/libstdc++.so.6
at main.cpp:5
- 按照介绍的在函数上使用noexcept修饰 (但是好像不行)
- 更换未gcc8
参考链接
- https:///u013272009/article/details/101458409
- https://gcc.gnu.org/legacy-ml/gcc-help/2011-11/msg00140.html
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55917
- https://zhuanlan.zhihu.com/p/59554240