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

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. python---time模块使用详解

    python中的time模块提供一些方法用来进行关于时间的操作,time模块中有以下方法可供使用: time() --- 返回当前时间的时间戳. 调用:time.time(),  可用于计算程序运行的 ...

  2. SVN初体验

    呐,部门领导要求今后项目部分内容要实行版本控制,因此有机会深入接触下SVN这门功课 ---------------------------------------------------------- ...

  3. ch5-Class 与 Style 绑定(v-bind:class v-bind:style)

    数据绑定一个常见需求是操作元素的 class 列表和它的内联样式. 因为它们都是属性 ,我们可以用v-bind 处理它们:只需要计算出表达式最终的字符串. 不过,字符串拼接麻烦又易错.因此,在 v-b ...

  4. jS判断浏览器终端

    在做移动端项目的时候,常常会遇到需要判断页面浏览终端的需求.要想判断是什么浏览器终端,先打印 navigator.userAgent 出来.所以收集了几种比较常用的方法: if(/(iPhone|iP ...

  5. 数据迁移过程中hive sql调优

    本文记录的是,在数据处理过程中,遇到了一个sql执行很慢,对一些大型的hive表还会出现OOM,一步一步通过参数的设置和sql优化,将其调优的过程. 先上sql ) t where t.num =1) ...

  6. BeginInvoke()使用

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  7. Python学习笔记(十三)

    Python学习笔记(十三): 模块 包 if name == main 软件目录结构规范 作业-ATM+购物商城程序 1. 模块 1. 模块导入方法 import 语句 import module1 ...

  8. Vector容器构造函数

    No1 vector(); No2 vector( const vector& c ); No3 explicit vector( size_type num, const TYPE& ...

  9. canvas+gif.js打造自己的数字雨头像

    前言 昨天 是1024程序员节,不知道各位看官过的怎么样.既然是过节,就要有个过节的样子,比方说,换个头像

  10. jQuery Ajax跨域问题简易解决方案

    场景:由于业务需求,需要在一个页面显示另外一个页面,并且右键查看源代码看不到一条链接. 实现方式:使用iframe来显示这个首页,至于首页的地址则使用jQuery Ajax来获取.html代码如下: ...