线上服务出现了重启告警,而且重启后继续。排查线上出现了一堆core,core信息显示如下:
这个是一个线程抛出的异常,但是看不到线程本身的代码,只可看到core文件堆栈栈钉出现在libstdc++库上。唯一业务代码在第6个栈帧。catch方块里的throw e代码上。
这里有几个问题。这里的异常实际上是在线程调度的函数抛出了异常。也就是thread->m_Runner->Execute()的时候,当时在异常抛出的时候,我们其实想要看到的是那个时候的堆栈内存快照。但是这个core发生的时候,已经退出了那个Execute函数,这个实际函数已经退出了,当时core点的堆栈已经展开了。然后函数跳过Execute函数,走到catch模块,到throw e位置,由于外部再无补货这个exception e的函数,函数在此结束。core信息反应的是此时throw e的内存快照。
这里引入了一个知识点就是:C++ 程序,如果 代码throw了 exception ,但是外部又没有 catch,那么一般会产生 coredump。而如果外面catch住了异常,这个就不会产生coredump,但是你也可以继续选择向上级抛异常,也可以忽略打点异常日志出来e.what()。 gcc有个宏_GLIBCXX_THROW_OR_ABORT定义你的行为是throw还是abort
我记得谷歌c++规范也是建议大家不写异常。但是如果团队内有人不遵守怎么办,我们可以在makefile加上(-gcc的 -fno-exceptions ,在编译阶段禁用异常机制。这样写了异常的代码不会通过。
gcc有个宏_GLIBCXX_THROW_OR_ABORT
的宏,該宏定義為
#ifndef _GLIBCXX_THROW_OR_ABORT
# if __cpp_exceptions
# define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC))
# else
# define _GLIBCXX_THROW_OR_ABORT(_EXC) (__builtin_abort())
# endif
#endif
有了第一个问题的铺垫,我们知道上层代码如果catch住了调用函数的异常,会导致core信息显示的不是调用函数本身的堆栈。所以要么函数外面不cacth,要么让抛__cxa_throw的函数直接挂掉。
本文的第一个问题正是,在 gcc 4.x 版本(gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) )产生的 coredump 文件中,没有 throw 时候的堆栈信息,导致不知道是哪里 throw 的,没法查问题。
我们继续看gcc 4.x 的 /libstdc++-v3/src/c++11/thread.cc:92 的代码就发现原因。这个gcc 4.x的线程执行的实现里面有个 catch(…),所以 stack unwind 了,就没了 throw 时候的 stack 。
以下是gcc4.x-6.x的实现
而gcc7.x以上已经重新实现了,以下是gcc 7.x以上的实现
这里就没有了cache。https://abcdabcd987.com/libstdc++-bug/
一个解决办法是可以升级 GCC 7 ,
因为不是所有的项目都方便切换到新版本的gcc,历史代码不好兼容新版本gcc,可以用更简单的办法:
__cxa_throw
,一个解决办法是通过改代码,hook __cxa_throw()
让每次生成的 coredump 都带上堆栈:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/cxxabi.h#L616
vim /usr/include/c++/4.8.2/cxxabi.h 看到__cxa_throw的声明。__cxa_throw() 是 libstdc++/libc++ 用于实现 throw 的函数。
https://libcxxabi.llvm.org/spec.html
我们可以重写(或者叫hook)
这个函数要加到你调用线程的那个文件里。比如我这里的Util/CThread.cpp(项目代码中线程执行函数)。
效果如下:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有