近日,我们视频平台提交基线测试时,出现录像下载失败崩溃的现象,通过仔细调试发现其是一个很典型的DLL HELL引发的栈溢出,由于在我们的项目中,引用了大量的DLL,而且有很多DLL是多方引用的,很容易出现版本不一致的问题,一般这种问题极难排查,需要耗费大量精力,现将此排查过程记录下,希望对后面类似问题的排查有所帮助。
一、首先观察问题出现的现象,并确定能否复现及复现的操作步骤
经过多方测试及确认,其复现步骤如下:
1. 登录平台客户端,并切换至录像回放tab页
2. 选择一个监控点,并进行录像搜索
3. 点击录像下载按钮,选择录像下载开始结束时间
4. 点击确定,客户端崩溃
二、 使用调试器附加运行,确定崩溃原因及崩溃代码行
一般我会使用windbg附加上去执行,当客户端崩溃后,会中断到调试器。
此时windbg输出如图所示:
首先观察到是错误码,很常见的access violation 0xc0000005,代表访问违例,一般这种问题是访问了错误的内存地址导致。最下面那行输出的是当前所执行到的代码,可以从图中看到,都是错误的值,这种现象意味着指令指针寄存器,EIP的值指向了错误的内存地址,一般出现这种问题最常见的有两种情况,一是EIP所执行的模块已经被卸载,二是发生了栈溢出,覆盖了栈上的返回地址。
可以输入r命令,查看下当前寄存器的值:
(传了几张图片发现还有水印。。)
可以看到EIP为0,比较麻烦的是ebp也为0,因为我们要看调用栈的话,windbg会借助ebp帮我们确定,如果ebp也错误了,我们查看调用栈就会遇到一定的麻烦。
输入k,果然不出所料,调用栈信息已经无法正常输出了
c
值得庆幸的是,esp的值看起来还有意义,我们借助esp的值来手动重建调用栈。
试探的看下esp指向的栈数据,输入dps esp