关于 mutex 的调试实例
来源:互联网 发布:网络兼职广告 编辑:程序博客网 时间:2024/04/30 10:21
今天解决了一个关于 mutex 的 bug.
程序每次登录成功就会创建两个线程. sign out 的时候可能会强制 Terminate 这两个线程.
当程序出现问题时用 Process Explorer 观察各个线程. 发现其中一个线程一直在等一个对象,
打开 windbg, 查看 WaitForSingleObject() 的参数. 找到了这个对象的句柄 6d0. 在 windbg 中执行:
0:001>!handle 6d0 f
Handle 6d0
Type Mutant
Attributes 0
GrantedAccess 0x1f0001:
Delete,ReadControl,WriteDac,WriteOwner,Synch
QueryState
HandleCount 4
PointerCount 8
Name none
Object Specific Information
Mutex is Owned
知道了这是一个 mutex. 我用 windbg 也不太熟. google 了一下 windbg mutex. 有所收获.
用这个帖子里的方法: http://blogs.thinktecture.com/ingo/archive/2006/08/05/414674.aspx
可以找到是那个线程拥有了这个 mutex
运行 kd, 发现是恰好是另一个线程获得了这个 mutex. 查看代码, 发现在线程中有这样的代码:
...
if (WaitForSingleObject(hmutex, 100) != WAIT_OBJECT_0) return FALSE;
return TRUE;
如果返回 TRUE, 则认为等到这个 mutex, 操作完成之后, 会调用 ReleaseMutex() 释放这个 mutex. 如果返回 FALSE, 则不会调用 ReleaseMutex().
问题就出在这里. 因为线程可能被强制结束. 那么就有可能没有释放 mutex. 这种情况下, MSDN 的描述是:
If a thread terminates without releasing its ownership of a mutex object, the mutex object is considered to be abandoned. A waiting thread can acquire ownership of an abandoned mutex object, but the wait function will return WAIT_ABANDONED to indicate that the mutex object is abandoned.
下一个线程在等这个"被抛弃"的 mutex 时. WaitForSingleObject() 的返回值是 WAIT_ABANDONED, 而不是 WAIT_OBJECT_0. 而且, 这种情况下, 线程的确获得了 mutex 的控制权. 但上面的代码没有考虑这种情况. 还是返回 FALSE, 导致后继的 ReleaseMutex() 没有调用. 因此导致另一个线程被死锁.
几点思考:
1. 一定不要强制结束线程. 反复强调这一点. 但程序员们还是照用不误.
2. 调用 API 的时候对于返回值的处理要很小心.
PS: 关于 Process Explorer 查看调用栈. 需要几个前提:
. 安装最新的 Process Explorer
. 安装最新的 windbg
. 设置好 _NT_SYMBOL_PATH, 比如:SRV*e:/symbols*http://msdl.microsoft.com/download/symbols
. 使用命令 symchk /r %windir% 将符号下载到本地. 这个比较费时, 可能要下载超过 1G 的符号文件
. 在 Process Explorer 菜单 Options/Configure Symbols 里设置正确的 Dbghelp.dll 路径以及 Symbols Path (默认是 _NT_SYMBOL_PATH 的值)
这些做好之后, 就可以在 Process Explorer 双击一个进程, 切换到 Threads 页. 等初始化完成之后, 双击一个线程, 就可以看到调用栈了.
- 关于 mutex 的调试实例
- 关于mutex的一些理解
- 关于mutex的一些思考
- 一个关于Lightweight Mutex 和 Heavyweight Mutex的实验
- 关于mutex
- 关于oracle mutex和latch的问题
- 关于memcache实现Mutex模式的解析
- 关于Mutex的构造函数参数设置
- 关于spinlock和mutex的性能差异
- 关于mutex与cond的用法
- 关于 IIS 关于未能创建 Mutex 问题的解决
- 利用Mutex实现应用程序的单实例运行
- 通过 Mutex/Semaphore 实现程序进程实例的控制
- 使用Mutex来保证单一进程实例的一种方法
- 利用Mutex实现应用程序的单实例运行
- 利用Mutex实现应用程序的单实例运行
- LinuxC/C++编程基础(7) boost::mutex的简单实例
- 关于.net中的mutex
- C#设计模式之Template Method
- C#设计模式之Builder
- windows 2000下"root/microsoftdns" 无效名称空间的解决方法
- WINCE5.0下开发winform应用程序一
- Windows下Linux开发环境设置--安装Cygwin及交叉编译工具链
- 关于 mutex 的调试实例
- C++、Java和C#的特性比较
- dwr介绍及概念
- 无刷新的四级联动下拉框实例(AjaxPro)
- 2007.06.29 9Fav就喜欢网发布最新版本 Version 1.5 - 首度公布应用API
- 帮个忙我有个小问题
- 华中科技大学马光志C++教学中的一个错误程序
- 浅析Javascript中继承和Prototype的关系http://www.cnblogs.com/meil/archive/2007/06/22/792895.aspx
- 简单的聊天程序