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

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

以上

发布了129 篇原创文章 · 获赞 73 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/u013272009/article/details/101458409
今日推荐