[原]崩溃在ole32!CStdMarshal::DisconnectSrvIPIDs

最近项目里遇到一个崩溃,不定期出现,很是头疼!今晚终于忍无可忍,下决心要干掉它!(于是用凉水洗了把脸,开始分析dump)希望凌晨的这篇总结对有相似经历的朋友有所启发!(看之前相关的几个dump可以猜到是有接口未释放的问题,但没有确认到底是哪个接口,本篇总结的主要目的是记录找到这个接口的过程)

 
用windbg打开dump文件,显示如下
 很明显是访问违例!从红框里的内容可知要取地址5bbc97f8的值,然后call之。但是5bbc97f8已经无效了!用 !address 5bbc97f8来看下该地址的信息
可知该地址确实已经不在内存中了!对应的模块已经被卸载了!
 
至此,可以知道崩溃的原因了:模块被卸载后,还要执行其中的代码!下面让我们继续分析,为什么模块卸载后还会执行其中的代码!
先用.ecxr切到出问题的线程,然后用kpn看下调用栈,如下图
可以知道是某个线程在调用CoUninitialize,执行com的线程清理工作!frame 0的 ole32!CStdMarshal::DisconnectSrvIPIDs调用导致了崩溃!看名字是要断开链接相关的!
ub 76f8bbe7 查看下崩溃前的几条指令
红框内的指令非常像COM函数(调用约定是stdcall)  eax是com指针 ecx是虚表指针
dword ptr[ ecx+8 ]是虚表中的第三项(32位下指针占4字节),回想IUnkown的前三个函数分别是 QueryInterface AddRef Release ,可以基本确认这里是在调用Release(),跟上下文也很搭!我们的猜测99%是正确的!
 
我们先小小总结下:来龙去脉基本是这样的,我们使用了一个com接口,但是我们并没有释放,在调用CoUninitialize的时候,com做线程清理相关工作,当清理到我们的接口的时候,因为我们的dll已经被卸载了,导致了访问违例!下面我们的任务是找出到底是哪个接口没释放,然后对照代码验证我们的猜测是否正确!
 
先用 lm a 5bbc97f8 确认下该地址属于哪个模块
用命令 .reload /f AccIME.dll=5bbb0000,5bbd8000-5bbb0000加载已经被卸载的模块及其对应的符号信息,并用 lm vm AccIME确认
注意:如果遇到如下错误,说明我们符号加载的有问题,可以打开!sym noisy选项后看输出日志来排查,用完后可以用!sym quiet恢复,具体使用方法可通过.hh !sym查看帮助文档
 
接下来我们用 ln 5bbc97f8 查一下该地址 附近对应的函数名
至此,我们可以看到是CCfgDpyScheme类相关的,可以把重点放到对此类的引用计数的使用上了!
本篇总结暂时写到这, 还需要弄明白几个问题:
1. 涉及引用计数的相关代码是否有问题
2. 为什么有时候会崩溃,有时候不崩溃
 
 
有结果后会再发一篇总结,敬请期待!
 
 
 





转载于:https://www.cnblogs.com/bianchengnan/p/6282616.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值