记一次线上问题定位过程

技术记一次线上问题定位过程 记一次线上问题定位过程出现问题,但不能快速修复系统在高峰期突然出现了大面积的core dump,通过gdbcore文件发现,是core在发送数据到另一个服务的地方,打开堆栈对

记住在线问题定位过程。

出现问题,但不能快速修复

在系统的高峰期,突然出现了大面积的堆芯。通过gdbcore文件,发现核心正在向另一个服务发送数据,打开栈对应的代码,这是公司的一个基本库文件,只是一个protobufmessage对象的简单声明。然而,核心一般不太可能出现在这个地方,否则程序中到处都会有类似的做法。为什么核心不在其他地方?是不是服务的其他线程使用gdb的线程应用所有bt来检查每个线程的堆栈造成的?大部分线程处于睡眠或等待状态信号(在线服务正在等待处理请求),这似乎不是问题,而且有点混乱。

Gdb打开其他机器实例的核心文件,发现线程1仍然有相同的堆栈信息,表明核心在protobufmessage对象中。稍微看一下protobuf声明对象的过程,无非是申请内存。没什么好怀疑的。如果这里有问题,服务中有很多使用pb对象的地方。为什么核心在同一个地方?

降级止损

我不知道该怎么办。查找服务日志,发现下游服务有大量请求超时。查这个下游服务的负载,发现负载很高。会不会是这种下游服务造成的?仔细想想,由于大量的实例同时存在,也会触发在线监控进程再次拉起服务,这样短时间内就会有大量的请求集中请求到一个下游服务的ip上(下游服务的实例有很多,但是由于服务本身无法在数据准备好之前注册到注册表中, 或者名称会暴露给上游,所以此时只能通过ip访问下游),所以下游服务的高负载不是核心的原因,批量重启请求被降级。 不幸的是,重启后,进程被服务了一小段时间,然后内核又回来了。

降级没用,继续找原因止损

看来要先找出核心的原因。既然都在线程1的同一个地方,这个地方应该有问题,所以我们可以从这里开始。查看当前请求中的数据,发现不同核心文件中字段的值是相同的。你能猜到一个特殊的请求会导致核心立即打电话给产品运营商,并首先阻塞这个流量吗?十分钟后发现核心真的不在了,观察半小时后服务正常。这时,已经是凌晨4点了。目前只能先这样止损,等第二天才能找出核心原因。

找到潜在原因,并修复

第二天上班仔细定位问题,或者就像昨晚一样,打开核心文件,查看堆栈信息,对比源代码,发现核心所在位置的源代码下面几行调用了一个序列化函数,这个函数是内联的,因为内联函数在编译的时候只把内容嵌入编译器,不做函数调用,所以如果核心在这里,就不会有堆栈信息。为了验证这种猜测,当gdb调试核心文件时,我有意打印了当前内联函数中的变量,结果确实如此。(反证:如果程序在这里执行之前是核心,是不可能打印出变量信息的),所以在序列化的过程中就断定是核心。然后关注序列化。实现系列化是公司2005年的代码,到现在已经16年了,不太可能出现什么问题。乍一看,序列化非常复杂,涉及内存设计和序列化编码过程。仔细看看,这可能意味着要将C的每个基本类型写入队列。迭代器先写元素的数量,然后写元素。没什么问题。继续挖掘,找到一个关键消息:序列化字符串时,它会决定大小,如果超过一定的大小,就会抛出异常。与这种特殊流量的某个字符串的长度相比,真的很长,这应该是问题所在。查了相关资料,发现是gcc的低版本。如果在底部抛出异常,就会被抓住然后直接退出,栈就不打印了。后来,有人报告了这个错误,并在gcc8中修复了它。难怪我看核心文件的时候从来没有看到核心的真正位置。对于这种情况的core,解决方案也很简单。修改旧代码(当然,如果更一般,只需hook __cxa_throw并打印出堆栈即可)。到目前为止,问题已经找到,解决方案已经找到。

在__cxa_throw中,底层是捕获异常,然后退出:

void * execute _ native _ thread _ routine(){ 0

尝试{

.

}catch(.){

STD : terminate();

}

}

查看代码

核心转储后,这样看核心文件。

方案

Hook__cxa_throw()在堆栈上生成每个coredump。

#包含iostream

#包括标准除外

#包含线程

Extern 'C' {//加上这三行代码,就可以通过hook __cxa_throw避免栈展开而直接中止。

void __cxa_throw(void* ex,void* info,void(* dest)(void *)){ : abort();}

}

void func(){ 0

引发STD : runtime _ error(' die ');

}

int main(){ 0

STD : thread t(func);

t . join();

返回0;

}

查看代码

影响

代码

https://github.com/longbo Zhan/sample/tree/master/hook _ exception

参考

https://byronhe.com/post/cpp-throw-coredump-with-backtrace/

https://abcdabcd987.com/libstdc-臭虫/

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/116874.html

(0)

相关推荐

  • 如何将后端baas化(baas替代后端程序员)

    技术怎样将后端BaaS化怎样将后端BaaS化,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。BaaS 化的核心其实就是把我们的后端应用封装成 RESTfu

    攻略 2021年12月21日
  • servlet和web应用服务器(servlet教程web)

    技术如何浅析Servlet的Web应用程序本篇文章给大家分享的是有关如何浅析Servlet的Web应用程序,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Ja

    攻略 2021年12月18日
  • 怎么解决Mysql中的Last_Errno报错问题

    技术怎么解决Mysql中的Last_Errno报错问题本篇内容主要讲解“怎么解决Mysql中的Last_Errno报错问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么解

    攻略 2021年11月18日
  • MySQL如何优化WHERE子句

    技术MySQL如何优化WHERE子句这篇文章主要为大家展示了“MySQL如何优化WHERE子句”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL如何优化WHERE子句”

    攻略 2021年11月1日
  • java反编译工具都有哪些(java防止反编译免费工具)

    技术Java反编译工具有哪些这篇文章主要介绍“Java反编译工具有哪些”,在日常操作中,相信很多人在Java反编译工具有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java反编译工具

    攻略 2021年12月24日
  • 怎样进行Vue2移动端开发环境搭建

    技术怎样进行Vue2移动端开发环境搭建这期内容当中小编将会给大家带来有关怎样进行Vue2移动端开发环境搭建,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。这里给出基于 Vue2 的移动端

    攻略 2021年11月16日