windbg分析句柄泄漏常用命令和步骤
分析命令
1、!htrace -enble。
2、执行重现过程,让进程句柄泄漏
3、通过!htrace -diff 找出有问题的栈。
关于STATUS_STOWED_EXCEPTION(0xC000027B)异常
简介
STATUS_STOWED_EXCEPTION,值为0xC000027B。代表的意思是"发生应用程序内部异常"。它定义在 ntstatus.h头文件里,如下:
/
// MessageId: STATUS_STOWED_EXCEPTION
//
// MessageText:
//
// An application-internal exception has occurred.
//
#define STATUS_STOWED_EXCEPTION ((NTSTATUS)0xC000027BL)
详细说明
本异常是UWP应用程序产生的异常类型。它是作为WinRT API(现在称为UWP)的一部分引入Windows 8.0的。这个异常已被故障点异常(0xC000027C)替换/增强。与POF异常一样,异常代码由WinRT框架生成。它不需要重新编译应用程序才能使用它。
当异步操作失败时,将引发这个异常。当通过RoOriginateException或RoOriginateLanguageException调用从工作线程报告异常时,将通过CaptureStackBackTrace函数调用收集当前线程的堆栈回溯(指令指针数组)。异常的堆栈回溯和HRESULT包装在一个iresteredrorinfo对象中,并通过WinRT的语言投影层路由到调用方。
如果调用方未处理异常,则会致命地抛出已装载的异常。因为抛出是延迟的,所以关联转储的当前上下文几乎没有值。原始问题的线程不再定期存在,如果存在,则已结束操作(意味着线程的堆栈内存已被覆盖)。这意味着函数参数和局部变量不可用。
异常结构信息填充
ExceptionAddress:
ExceptionCode: c000027b
ExceptionFlags: 00000001
NumberParameters: 2
Parameter[0]: 000002414ffc8680//是指向以STOWED_EXCEPTION_INFORMATION_HEADER开头的结构的指针数组的起始地址。自Windows 8.1以来,已使用的版本是STOWED_EXCEPTION_INFORMATION_V2。
Parameter[1]: 000000000000003//是数组中指针的数目。
WinDbg里查找线程栈的StackBase 和 StackLimit 的硬偏移
User Mode 32bit
0:000> dt nt!_TEB.Stack*
ntdll!_TEB
+0x000 NtTib :
+0x004 StackBase : Ptr Void
+0x008 StackLimit : Ptr Void
User Mode 64bit
0:000> dt nt!_TEB NtTib.Stack*
ntdll!_TEB
+0x000 NtTib :
+0x008 StackBase : Ptr64 Void
+0x010 StackLimit : Ptr64 Void
Kernel Mode 32bit
0:000> dt nt!_KTHREAD Stack*
ntdll!_KTHREAD
+0x01c StackLimit : Ptr Void (NT v5.0 - Windows 2000)
+0x01c StackLimit : Ptr Void (NT v5.1 - Windows XP SP3)
+0x01c StackLimit : Ptr Void (NT v5.2 - Windows 2003 SP2)
+0x02c StackLimit : Ptr Void (NT v6.0 - Windows Vista/2008)
+0x02c StackLimit : Ptr Void (NT v6.1 - Windows 7/2008R2)
+0x15c StackBase : Ptr Void (NT v5.0 - Windows 2000)
+0x15c StackBase : Ptr Void (NT v5.1 - Windows XP SP3)
+0x158 StackBase : Ptr Void (NT v5.2 - Windows 2003 SP2)
+0x174 StackBase : Ptr Void (NT v6.0 - Windows Vista/2008)
+0x194 StackBase : Ptr Void (NT v6.1 - Windows 7/2008R2)
Kernel Mode 64bit
0:000> dt nt!_KTHREAD Stack*
ntdll!_KTHREAD
+0x??? StackLimit : Ptr64 Void(NT v5.1 - Windows XP SP3)
+0x??? StackLimit : Ptr64 Void(NT v5.2 - Windows 2003 SP2)
+0x030 StackLimit : Ptr64 Void(NT v6.0 - Windows Vista/2008)
+0x030 StackLimit : Ptr64 Void(NT v6.1 - Windows 7/2008R2)
+0x??? StackBase : Ptr64 Void(NT v5.1 - Windows XP SP3)
+0x??? StackBase : Ptr64 Void(NT v5.2 - Windows 2003 SP2)
+0x250 StackBase : Ptr64 Void(NT v6.0 - Windows Vista/2008)
+0x278 StackBase : Ptr64 Void(NT v6.1 - Windows 7/2008R2)
Win10下装 VC6.0单步调试报((OLE32.DLL): 0xC0000005: Access Violation)
想在win10上重温下经典VC++6.0,结果单步调试时弹出个异常对话框,报((OLE32.DLL): 0xC0000005: Access Violation)
解决方法如下:
1、菜单 工具->选项 中的调试,反汇编下的来源注解取消
2、点确定保存设置,然后即可单步调试
3、再将工具->选项 中的调试,反汇编下的来源注解勾上
WinDbg文件关联和资源管理器上下文菜单
很长一段时间以来,我有一个注册表文件来为WinDbg创建上下文菜单项。这些条目允许您选择x86或x64调试器。在公司内部,我有另一个版本的注册表文件,其中包含了私有符号服务器的另外两个上下文菜单项。你可以在这个截图中看到我在内部添加的所有4个选项。
注意,注册表文件假定WinDBG安装在c:\调试器_x86和c:\调试器中(分别用于x86和AMD64调试器)。
注册表项传入Microsoft公共符号服务器(http://msdl.Microsoft.com/download/symbols)和Microsoft专用符号服务器的符号路径。在这两种情况下,符号都通过SRV*链接在本地缓存(例如c:\符号)。与体系结构条目非常相似,这种技术为您提供了一种在公共和私有符号之间切换的快速方法(在我的例子中)。符号路径的传递,而不是使用-NT_symbol_path环境变量,是绕过WinDBG所做的具体化的唯一方法。如果设置了环境变量,则该变量将位于传递的符号路径的前面。这意味着仍然可以使用环境变量路径而不是传递路径。我承认,这只是一个问题,为人们需要支持的两个符号商店和绝大多数人,环境变量是一个更好的方式去做。如果这样做,只需删除命令行的-y部分。
注册表文件为所有转储变量建立关联,包括反射转储文件(*.ini)。反射转储可以使用ProcDump和-r开关(例如ProcDump.exe-r-ma notepad.exe)进行。目前,我使用Visual Studio 2010键来获取图标,并且仍然支持通过Open条目在Visual Studio中打开转储(我不知道您为什么要这样做)。
我做的另一件事是加载常用的调试器扩展。在这个(示例)注册表文件中,我只是通过-a开关(为MSDN Magazine调试API系列创建的扩展名)包含了自己的一个扩展名(myext.dll)。如果要加载更多内容,只需在命令行中包含多个-a myext.dll条目。(另请注意,如果对cdb执行相同操作,则不能在-a和dll名称之间留有空格)。在我的个人版本中,我加载了六个扩展。
您可能需要考虑的一件事是添加-WX开关以忽略默认工作区。我亲自按照自己喜欢的方式设置默认工作区(命令窗口停靠、在主监视器上最大化WinDbg、为每个文本类型设置字体颜色等),并将其用作每个新调试会话的模板。因此,我不希望使用-WX开关(这是一个双负数),因为我希望应用工作区。但是,如果要始终使用“开箱即用”默认值,请添加-WX开关。
Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\.dmp]
@="VisualStudio.dmp.10.0"[HKEY_CLASSES_ROOT\.hdmp]
@="VisualStudio.dmp.10.0"[HKEY_CLASSES_ROOT\.mdmp]
@="VisualStudio.dmp.10.0"[HKEY_CLASSES_ROOT\.kdmp]
@="VisualStudio.dmp.10.0"[HKEY_CLASSES_ROOT\.ini]
@="VisualStudio.dmp.10.0"[HKEY_CLASSES_ROOT\VisualStudio.dmp.10.0\shell]
@="WinDbg_x64_public"[HKEY_CLASSES_ROOT\VisualStudio.dmp.10.0\shell\WinDbg_x86_public]
@="Open with WinDbg x86 (Public)"[HKEY_CLASSES_ROOT\VisualStudio.dmp.10.0\shell\WinDbg_x86_public\Command]
@="\"C:\\Debuggers_x86\\windbg.exe\" -z \"%1\" -a myext.dll -y \"SRV*C:\\Symbols*http://msdl.microsoft.com/download/symbols\\ [HKEY_CLASSES_ROOT\VisualStudio.dmp.10.0\shell\WinDbg_x64_public]
@="Open with WinDbg x64 (Public)"[HKEY_CLASSES_ROOT\VisualStudio.dmp.10.0\shell\WinDbg_x64_public\Command]
@="\"C:\\Debuggers\\windbg.exe\" -z \"%1\" -a myext.dll -y \"SRV*C:\\Symbols*http://msdl.microsoft.com/download/symbols\\