我们有一个服务跑在微软云的所有宿主机上。最近发现某一台机器上该服务进程持续崩溃。
崩溃原因是访问了一个无效指针,对应的代码如下

serviceListIniBuffer.AppendF("ServerList=%s\r\n",
                                               m_newServiceList.config->GetStringParameter("Manifest", "ServerList", "").c_str());

从dump和live repo中发现,无效指针的来自AppendF函数的第一个参数。
但奇怪的,该参数是一个写死的字符串,这怎么会发生呢?

看汇编代码

00007ff6`36961907 4889442420 mov qword ptr [rsp+20h],rax
00007ff6`3696190c 4c8d0d45270b00 lea r9,[GetAndRunServices!`string'+0xfd8 (00007ff6`36a14058)]
00007ff6`36961913 4c8d054e270b00 lea r8,[GetAndRunServices!`string'+0xfe8 (00007ff6`36a14068)]
00007ff6`3696191a 488d5500 lea rdx,[rbp]
00007ff6`3696191e 488b8f98030000 mov rcx,qword ptr [rdi+398h]
00007ff6`36961925 e8f649f3ff call GetAndRunServices!apsdk::configuration::IConfiguration::GetStringParameter (00007ff6`36896320)
00007ff6`3696192a 90 nop
00007ff6`3696192b 4883781810 cmp qword ptr [rax+18h],10h
00007ff6`36961930 7203 jb GetAndRunServices!GetAndRunServices2::GenerateOMNewServiceListFile+0x9e5 (00007ff6`36961935)
00007ff6`36961932 488b00 mov rax,qword ptr [rax]
00007ff6`36961935 4c8bc0 mov r8,rax
00007ff6`36961938 488d1541270b01 lea rdx,[00007ff6`37a14080]
00007ff6`3696193f 488d4d20 lea rcx,[rbp+20h]
>>>>>>>>>>>>>>>>>>>>00007ff6`36961943 e8981ef3ff call GetAndRunServices!apsdk::DynStringT<127>::AppendF (00007ff6`368937e0)

具体的崩溃发生在AppendF里面。但问题是无效指针导致的,和被调函数AppendF无关。为了省略篇幅就略过AppendF部分了。

这里可以看到,rcx应该保存的是serviceListIniBuffer的this指针。因为C默认从右向左压参数,所以rdx对应的应该是第一个参数,r8对应的应该是第二个参数。

0:000> da r8
00000001`0a3a48c0 "25.66.164.187:25.66.164.4:25.66."
00000001`0a3a48e0 "164.251:25.66.165.4"

0:000> da rdx
00007ff6`37a14080 "????????????????????????????????"

果然,rdx就是无效啊。

仔细看一下前面的汇编,比如在调用GetStringParameter的时候,也会用到写死的字符串。比如下面两句就是
00007ff6`3696190c 4c8d0d45270b00 lea r9,[GetAndRunServices!`string'+0xfd8 (00007ff6`36a14058)]
00007ff6`36961913 4c8d054e270b00 lea r8,[GetAndRunServices!`string'+0xfe8 (00007ff6`36a14068)]

可以看到,这些字符串都是从GetAndRunServices!`string'这个全局表里面读入的。 这两个地址也都准确落入了执行文件的地址范围:
0:000> lmf
start end module name
00007ff6`36880000 00007ff6`36bda000 GetAndRunServices C:\App\getandrunservices.ap_10_09_10_8_5003_2510\GetAndRunServices.exe

而出问题的地址是00007ff6`37a14080,的确也在执行文件地址范围外。
但仔细看一下,00007ff6`37a14080这个地址和合法区间比较,只有一个bit不一样:
00007ff6`3[7]a14080 00007ff6`3[6]a14080
这里7和6在二进制上面就差了末尾的bit。 如果我手动换一成6看看呢:

0:000> da 00007ff6`36a14080
00007ff6`36a14080 "ServerList=%s.."

果然就和源代码match了。

这个迷如何解释呢?首先可能的是这个执行文件有损害。但是现在执行文件默认都有完整性和签名保护,可能性不大。把文件拷贝出来和其它没有问题的文件比,的确也一模一样。
还可能是病毒?但是云上的宿主机器都是绝对隔离的。从live debug过程中看,没见到用户态有什么注入。
剩下的原因是硬件问题。内存或者CPU读取流水线遇上某二进制规律的时候触发数据损坏。

这就是我目前的推断。下周和有经验的工程师聊一下看看这样分析对不对。以前也遇上过疑似硬件问题导致的崩溃,但今天是第一次现场抓住!
如果你有类似经历或者经验,请指点和分享。

疑似CPU或者内存故障导致进程崩溃的更多相关文章

  1. inux如何查看当前占用CPU或内存最多的进程

    一.可以使用以下命令查使用内存最多的进程 方法1: ps -aux | sort -k4nr | head -K 如果是10个进程,K=10,如果是最高的三个,K=3 说明:ps -aux中(a指代a ...

  2. 查看占用cpu和内存最多的进程

    linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: ps aux|head -;ps aux|grep -v PID|sort -rn -k +|head linux下获取占用内存 ...

  3. linux系统PS命令,按CPU、内存使用率对进程排序

    https://blog.csdn.net/weixin_42123737/article/details/90081318

  4. W3wp.exe占用CPU及内存资源

    问题背景 最近使用一款系统,但是经常出现卡顿或者用户账号登录不了系统.后来将问题定位在了服务器中的“w3wp.exe”这个进程.在我们的用户对系统进行查询.修改等操作后,该进程占用大量的CPU以及内存 ...

  5. 线程崩溃为什么不会导致 JVM 崩溃

    大家好,我是坤哥 网上看到一个很有意思的据说是美团的面试题:为什么线程崩溃崩溃不会导致 JVM 崩溃,这个问题我看了不少回答,但都没答到根本原因,所以决定答一答,相信大家看完肯定会有收获,本文分以下几 ...

  6. linux的PS进程和作业管理(进程调度,杀死进程和进程故障-僵尸进程-内存泄漏)

     Ps进程和作业管理 1.查看进程ps 1.格式 ps   ---查看当前终端下的进程 3种格式: SYSV格式   带 - 符号 BSD格式  不带 - 符号 GNU格式   长选项 2.ps -a ...

  7. 如何按名称或PID查找一个进程?如何按端口号查找一个进程?如何查看一个进程的CPU和内存、文件句柄使用情况?如何查看CPU利用率高的TOP10进程清单?如何根据PID强制终止进程?

    如何按名称或PID查找一个进程?如何按端口号查找一个进程?如何查看一个进程的CPU和内存.文件句柄使用情况?如何查看CPU利用率高的TOP10进程清单? 目录 如何按名称或PID查找一个进程?如何按端 ...

  8. Linux(CentOS) 如何查看当前占用CPU或内存最多的K个进程

    一.可以使用以下命令查使用内存最多的K个进程 方法1: ps -aux | sort -k4nr | head -K 如果是10个进程,K=10,如果是最高的三个,K=3 说明:ps -aux中(a指 ...

  9. Linux如何查看当前占用CPU或内存最多的K个进程

    一.可以使用以下命令查使用内存最多的K个进程 方法1: ps -aux | sort -k4nr | head -K 如果是10个进程,K=10,如果是最高的三个,K=3 说明:ps -aux中(a指 ...

随机推荐

  1. 经典算法研究系列:二、Dijkstra 算法初探

    July   二零一一年一月 本文主要参考:算法导论 第二版.维基百科. 一.Dijkstra 算法的介绍 Dijkstra 算法,又叫迪科斯彻算法(Dijkstra),算法解决的是有向图中单个源点到 ...

  2. 由 System.arraycopy 引发的巩固:对象引用 与 对象 的区别

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  3. 解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HO问题

    原因:因为你的编译工具(eclipse/Myeclipse...)没有添加jdk.添加M2_HOME的环境变量. 解决: ①:window->Preferences->java->I ...

  4. 深入浅出AQS之组件概览

    之前分析了AQS中的独占锁,共享锁,条件队列三大模块,现在从结构上来看看AQS各个组件的情况. 原文地址:http://www.jianshu.com/p/49b86f9cd7ab 深入浅出AQS之独 ...

  5. Opencv处理鼠标事件-OpenCV步步精深

    在图片上双击过的位置绘制一个 圆圈 鼠标事件就是和鼠标有关的,比如左键按下,左键松开,右键按下,右键松开,双击右键等等. 我们可以通过鼠标事件获得与鼠标对应的图片上的坐标.我们通过以下函数来调用查看所 ...

  6. 3.ElasticSearch的倒排索引

    一. 正向索引 常规的索引建立方式 文档---> 关键词的映射过程(正向索引) 比如: 我有很多个文章,如果想查询其中几个文章是否含有刘耀这个关键词,那么我就需要打开所以文章,找到里面含义刘耀的 ...

  7. vue学习前奏——webpack

    "工欲善其事必先利其器",要想学习vue,首先需要我们去了解webpack,便于后期快速构建运行项目.废话不多说,下面开始介绍在开始一个vue项目前我们需要对webpack有一定的 ...

  8. (转)十分钟入门pandas

    本文是对pandas官方网站上<10 Minutes to pandas>的一个简单的翻译,原文在这里.这篇文章是对pandas的一个简单的介绍,详细的介绍请参考:Cookbook . 习 ...

  9. Linux入门(17)——Ubuntu16.04显示内存CPU网速等(System Monitor)

    终端查看内存状况有两个命令 top htop 如果系统没有安装htop的话,那就安装一下. 然而这样比较麻烦,System Monitor是个不错的选择,System Monitor可以显示网速,内存 ...

  10. python第二课

    本节内容 1.列表list.切片 2.字典dict