项目里安装了UIA相关的钩子来监听UIA相关事件,退出的时候偶尔会崩溃在ComFriendlyWaitMtaThreadProc中,如下

 从上图可以看出 是访问到无效的地址了,用!address 07acf914看下地址信息

 确实是不可访问的,但是为啥呢?用ub看了下前面的代码

 从红框中我们可以看出edi是指向第一个参数(ebp+8指向第一个参数),用k命令看下调用栈,如下
原来ComFriendlyWaitMtaThreadProc 是线程回调函数啊,那么edi就指向了传入的参数!通过查看CreateThread的原型我们可以知道 ComFriendlyWaitMtaThreadProc 原型是typedef DWORD ( __stdcall *LPTHREAD_START_ROUTINE )(LPVOID lpThreadParameter);
综上可知,参数lpThreadParameter出问题了,指向了一个非法的地址!
有两种猜测:
1. 调用线程用了一个栈上的局部变量,但是调用线程挂掉了,栈上的内容无效了!
2. 代码中存在bug,传递参数的时候就传的有问题!(可能性太低了)
 
单纯的从dump中看不出更多的信息了!于是我决定给 ComFriendlyWaitMtaThreadProc下断点,看看是否能找到是谁创建了这个线程!
  1. bu uiautomationcore!ComFriendlyWaitMtaThreadProc
  2. g
断下来后用~*k查看当前所有线程,逐一查看,是否有可疑线程,发现11号线程很可疑

 
 经过一系列的反汇编,逻辑确认,最终确认11号线程是我们要找的线程!
 
结论:
当主程序退出时,0号线程(主线程)做清理工作,会等待11号线程(卸载钩子)一定的时间,如果超时了就将其强行杀死(正是这个TerminateThread的调用导致了崩溃)! 18号线程会用11号线程传过来的线程参数,如果11号线程被意外杀死了,那么11号线程中的操作就是未定义的!!!至此真相大白!(中间还有很多相关细节太琐碎了,这里直接写出了结论)
 
 
 
说明:
uia在装钩子和卸载钩子的时候都会做类似的操作,而且会做很多次,具体没再仔细研究!
 
高能预警:
不要使用TerminateThread!!!事实再次残酷的证明了,调用TerminateThread不会有好果子吃!

[原]调试ComFriendlyWaitMtaThreadProc崩溃的更多相关文章

  1. [原]调试实战——使用windbg调试崩溃在ComFriendlyWaitMtaThreadProc

    原调试debugwindbgcrash崩溃COM 前言 这是几年前在项目中遇到的一个崩溃问题,崩溃在了ComFriendlyWaitMtaThreadProc()里,没有源码.耗费了我很大精力,最终通 ...

  2. [原]调试实战——使用windbg调试崩溃在ole32!CStdMarshal::DisconnectSrvIPIDs

    原调试debugwindbg崩溃crash 前言 最近程序会不定期崩溃,很是头疼!今晚终于忍无可忍,下决心要干掉它!从之前的几个相关的dump可以猜到是有接口未释放导致的问题,但没有确认到底是哪个接口 ...

  3. [原]调试实战——程序CPU占用率飙升,你知道如何快速定位吗?

    原调试debugwindbghangprocess explorer 前言 如果我们自己的程序的CPU Usage(CPU占用率)飙升,并且居高不下,很有可能陷入了死循环.你知道怎么快速定位并解决吗? ...

  4. [原]调试实战——使用windbg调试DLL卸载时的死锁

    原调试debugwindbg死锁deadlock 前言 最近我们的程序在退出时会卡住,调查发现是在卸载dll时死锁了.大概流程是这样的:我们的dll在加载的时候会创建一个工作线程,在卸载的时候,会设置 ...

  5. [原]调试实战——使用windbg调试TerminateThread导致的死锁

    原调试debugwindbg死锁deadlock 前言 项目里的一个升级程序偶尔会死锁,查看dump后发现是死在了ShellExecuteExW里.经验少,不知道为什么,于是在高端调试论坛里发帖求助, ...

  6. [原]调试实战——使用windbg调试excel启动时死锁

    原调试debugwindbg死锁deadlock 前言 这是几年前在项目中遇到的一个死锁问题,在博客园发布过.我对之前的笔记进行了整理重新发布于此. 本文假设小伙伴们知道一些基本概念,比如什么是.du ...

  7. [原]调试没有符号的 iOS 应用

    说明: 这里的调试是指使用 lldb 远程调试 iOS 应用 设置断点是指在 ObjC 方法上设置断点 使用场景: 1.调试被 strip 了的 iOS 应用 2.调试被 strip 了的 iOS 系 ...

  8. MDK5在调试中崩溃,提示“IDE已停止工作”

    出问题的原因是路径名太长,换个深度浅一点的路径就好了. 要注意,更换路径之后,要全部重新编译,否则调试的时侯MDK还会找旧路径的源代码.(嗯,MDK毛病是很多!)

  9. 内存转储文件调试系统崩溃bug

    百度百科:内存转储文件 内存转储是用于系统崩溃时,将内存中的数据转储保存在转储文件中,供给有关人员进行排错分析用途.而它所保存生成的文件就叫做内存转储文件. 内存转储文件也被称作虚拟内存,它是用硬盘里 ...

随机推荐

  1. QMap

    #include <QCoreApplication> #include<QMap> #include<QDebug> int main(int argc, cha ...

  2. SQLSERVER2012 Audit (审核)功能

    数据库表结构和数据有时会被无意或者恶意,或者需要追踪最近的数据结构变更记录,以往必须通过日志查询,SQL Server2008开始提供了 审核(Audit )功能,SQL2012有所升级,利用它可以实 ...

  3. spring boot + gradle[草稿]

    入门文档:https://github.com/qibaoguang/Spring-Boot-Reference-Guide 安装gradle 官方下载 https://gradle.org/grad ...

  4. Git tag push 到远端仓库

    很早之前,我们就提到过用Git tag来给工程打上标签,但是这个命令只是在本地仓库打标签而已, 为了能把标签同步到远程服务器,我们可以这样做: 默认情况下,git push并不会把tag标签传送到远端 ...

  5. 关于ES6的 模块功能 Module 中export import的用法和注意之处

    export default 的用法 export default命令用于指定模块的默认输出.显然,一个模块只能有一个默认输出,因此export deault命令只能使用一次.所以,import命令后 ...

  6. 算法第四版 用eclipse实现书中UnionFind例子

    一 安装环境 直接下载algs4.exe 下载完成后C:\Users\zle 下面会有algs4 文件夹 原文: Our installer downloads, installs, and conf ...

  7. Qt timer学习

    QTimer(重复和单发计时器) 应用QTimer时,先创建一个QTimer类,利用connect将timeout()与对应槽函数连接,在调用start()函数设置定时器时间间隔,每经过设置时间后,定 ...

  8. SSM——(二):easyUI的CRUD

    1.在WebContent下新建admin目录,添加index.html(用来显示user表的CRUD): 总结: 1.datagrid接收的必须是json数据: 2.使用分页插件会自动向后台传递St ...

  9. UVA 11624 BFS的妙用

    题意: 迷宫里起火了,有若干个障碍物,有多个起火点,起火点每经过一个时间间隔就向它的上下左右相邻的格子扩散. 有个倒霉的人好像叫做“Joe”,他要逃出来,他每次可以向上下左右任意移动一格,但是即要避开 ...

  10. js中子父页面数据传递与方法调用

    A父页面 ,B为子页面 1.父页面调用子页面 A中调用B中方法:self.frames[iframeName].BFunction(); 注:iframeName:为父页面中iframe的name属性 ...