记一次线上问题定位过程

技术记一次线上问题定位过程 记一次线上问题定位过程出现问题,但不能快速修复系统在高峰期突然出现了大面积的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)

相关推荐

  • oracle18c和12c的区别(oracle20c新特性)

    技术Oracle 数据库12c新特性有哪些这篇文章将为大家详细讲解有关Oracle 数据库12c新特性有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。  1. 在线重命名和重新定位

    攻略 2021年12月13日
  • Python中数据结构list怎么用

    技术Python中数据结构list怎么用这篇文章给大家分享的是有关Python中数据结构list怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。list是一种有序可重复的集合,可以随时添加

    攻略 2021年11月24日
  • ad pads allegro哪个好学(halcyon ad blocker)

    技术如何进行GoAead RCE预警分析如何进行GoAead RCE预警分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。0x00 背景介绍12月12日,M

    攻略 2021年12月20日
  • 适用于所有人的图形和艺术字设计软件 Art Text中文激活版

    技术适用于所有人的图形和艺术字设计软件 Art Text中文激活版 适用于所有人的图形和艺术字设计软件 Art Text中文激活版Art Text 4 Mac破解版 (艺术字和图标设计软件)
    适用于所

    礼包 2021年12月7日
  • Tomcat中如何清理缓存

    技术Tomcat中如何清理缓存这篇文章将为大家详细讲解有关Tomcat中如何清理缓存,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、关于Tomcat“缓存”的介绍 很多时候

    攻略 2021年12月11日
  • 雷锋的故事50个字,冰心的五个真实故事50字

    技术雷锋的故事50个字,冰心的五个真实故事50字1雷锋的故事50个字、童年好学冰心4岁时,就在母亲和舅舅杨子敬的督促下,开始读书认字。母亲教她“字片”,舅舅教她课本,并给她讲《三国》故事。
    她7岁时,开始读《三国演义》,

    生活 2021年10月30日