C++ 程序抛异常产生的 core 文件,无法显示正确的函数调用栈信息(备忘)

问题

比如,如下程序:

#include <thread>
#include <string>
#include <chrono>

int f()
{
        throw int(1);
}

int f2()
{
        f();
}

int main()
{
        std::thread t2(f2);
        t2.join();
}

编译,执行:

g++ main.cpp -o test -std=c++11 -pthread
./test

会产生 core 文件:

[fananchong@host-192-168-21-22 bin]$ gdb test core.15501
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/fananchong/valkyrie/Runtime_ZT_QA/bin/test...(no debugging symbols found)...done.
[New LWP 15502]
[New LWP 15501]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal 6, Aborted.
#0  0x00007fe0b6db3337 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:55
55        return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
(gdb) bt
#0  0x00007fe0b6db3337 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:55
#1  0x00007fe0b6db4a28 in __GI_abort () at abort.c:90
#2  0x00007fe0b78df7d5 in __gnu_cxx::__verbose_terminate_handler () at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#3  0x00007fe0b78dd746 in __cxxabiv1::__terminate (handler=<optimized out>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:38
#4  0x00007fe0b78dd773 in std::terminate () at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:48
#5  0x00007fe0b7934105 in std::(anonymous namespace)::execute_native_thread_routine (__p=<optimized out>) at ../../../../../libstdc++-v3/src/c++11/thread.cc:92
#6  0x00007fe0b7152e65 in start_thread (arg=0x7fe0b6d7c700) at pthread_create.c:307
#7  0x00007fe0b6e7b88d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb)

无法正确显示 f() 出现异常

解决方法

解决方法很多,根据项目情况,最佳方法为, 增加 noexcept 关键字

如下:

#include <thread>
#include <string>
#include <chrono>

int f()
{
        throw int(1);
}

int f2() noexcept
{
        f();
}

int main()
{
        std::thread t2(f2);
        t2.join();
}

编译,执行:

g++ main.cpp -o test -std=c++11 -pthread
./test

会产生 core 文件:

[fananchong@host-192-168-21-22 bin]$ gdb test core.12905
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/fananchong/valkyrie/Runtime_ZT_QA/bin/test...(no debugging symbols found)...done.
[New LWP 12906]
[New LWP 12905]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal 6, Aborted.
#0  0x00007f3683482337 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:55
55        return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
(gdb) bt
#0  0x00007f3683482337 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:55
#1  0x00007f3683483a28 in __GI_abort () at abort.c:90
#2  0x00007f3683fae7d5 in __gnu_cxx::__verbose_terminate_handler () at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#3  0x00007f3683fac746 in __cxxabiv1::__terminate (handler=<optimized out>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:38
#4  0x00007f3683fab6f9 in __cxa_call_terminate (ue_header=0x7f367c000920) at ../../../../libstdc++-v3/libsupc++/eh_call.cc:54
#5  0x00007f3683fac364 in __cxxabiv1::__gxx_personality_v0 (version=<optimized out>, actions=<optimized out>, exception_class=<optimized out>, ue_header=<optimized out>,
    context=<optimized out>) at ../../../../libstdc++-v3/libsupc++/eh_personality.cc:676
#6  0x00007f3683a458a3 in _Unwind_RaiseException_Phase2 (exc=exc@entry=0x7f367c000920, context=context@entry=0x7f368344ab90) at ../../../libgcc/unwind.inc:62
#7  0x00007f3683a45c3b in _Unwind_RaiseException (exc=0x7f367c000920) at ../../../libgcc/unwind.inc:131
#8  0x00007f3683fac986 in __cxxabiv1::__cxa_throw (obj=0x7f367c000940, tinfo=0x604120 <_ZTIi@@CXXABI_1.3>, dest=0x0) at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:82
#9  0x0000000000400df6 in f() ()
#10 0x0000000000400dff in f2() ()
#11 0x00000000004020f9 in int std::_Bind_simple<int (*())()>::_M_invoke<>(std::_Index_tuple<>) ()
#12 0x0000000000402053 in std::_Bind_simple<int (*())()>::operator()() ()
#13 0x0000000000401fec in std::thread::_Impl<std::_Bind_simple<int (*())()> >::_M_run() ()
#14 0x00007f3684003070 in std::(anonymous namespace)::execute_native_thread_routine (__p=<optimized out>) at ../../../../../libstdc++-v3/src/c++11/thread.cc:84
#15 0x00007f3683821e65 in start_thread (arg=0x7f368344b700) at pthread_create.c:307
#16 0x00007f368354a88d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) quit

该 core 文件, 第 #10 #9 #8 正确显示了 f() 内抛出了异常

参考资料

以上有同事给出的解决方案,主要参考至:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55917
https://zhuanlan.zhihu.com/p/59554240

里面讨论给出了多种解决方法

以上

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fananchong2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值