应用程序初始化失败(0xC0000034)错误的定位方法
2009-04-10 at 01:53 pm 饶趣 通常在遭遇应用程序启动过程中应用程序初始化失败或应用程序配置错误的时候,我们大致能够断定该错误产生的原因在于某个dll模块加载失败或是与manifest指定版本不匹配造成的。在今天的一例 0xC0000034 错误处理过程中摸索出两个比较可行的方法来处理。
问题重现:
在问题锁定之后,我们能够重新布置故障现场使问题重现,通过 调试环境我们能够看到相关模块的加载过程,而在遭遇的一例case中,是由于其中ATL80.dll缺失出现了类似问题:
“aliim.exe”: 已加载“H:\Assist\IMClient-RV\bin\Debug\AliIM.exe”,已加载符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\ntdll.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\kernel32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\comctl32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\advapi32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\rpcrt4.dll”,未加载任何符号。
…………
“aliim.exe”: 已加载“C:\WINDOWS\system32\oleaut32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\WinSxS\x86_Microsoft.VC80.ATL_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_cbb27474\ATL80.dll”,已加载符号。
此时,我们可以简单的将 C:\WINDOWS\WinSxS\x86_Microsoft.VC80.ATL_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_cbb27474\ATL80.dll 文件重新命名,令其无法被加载,启动 AliIM.exe 的时候就会出现下图:
“aliim.exe”: 已加载“H:\Assist\IMClient-RV\bin\Debug\AliIM.exe”,已加载符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\ntdll.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\kernel32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\comctl32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\advapi32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\system32\rpcrt4.dll”,未加载任何符号。
…………
“aliim.exe”: 已加载“C:\WINDOWS\system32\oleaut32.dll”,未加载任何符号。
“aliim.exe”: 已加载“C:\WINDOWS\WinSxS\x86_Microsoft.VC80.ATL_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_cbb27474\ATL80.dll”,已加载符号。
此时,我们可以简单的将 C:\WINDOWS\WinSxS\x86_Microsoft.VC80.ATL_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_cbb27474\ATL80.dll 文件重新命名,令其无法被加载,启动 AliIM.exe 的时候就会出现下图:

方法一:有对比有真相
上面的重现方法实际上就是根据观察调试过程中模块加载顺序后定位到的模块缺失来使过程重现的,这就是我们的第一个方法:对此调试过程中的模块加载输出:
在一个正常的加载过程中,模块加载信息会顺利的往下持续打印出来,而在异常环境中会看到如下的输出内容:
…………
“aliim.exe”: 已加载“C:\WINDOWS\system32\oleaut32.dll”,未加载任何符号。
调试器:: 在进程加载过程中引发了未处理的无法继续的异常
程序“[4024] aliim.exe: 本机”已退出,返回值为 -1073741772 (0xc0000034)。
这里原本应该输出 ATL80.dll 加载成功的消息不再出现了,但是通过对比两次加载输出就能够知道加载失败的是 ATL80.dll,但是需要注意的是,WinSxS 下的 ATL80 版本不只一个,具体缺失的是哪一个可以通过打开 WinSxS 下的目录进行确定。
这是一种方法,但是在本机却不是那么有效的一种方法,因此在本机出现错误的时候我们甚至都没有机会能够比较正常过程中是怎样的情况。所以,这种方法实际上生效的场景是用于辅助解决远程机器上用户应用程序加载失败的模块定位。
在一个正常的加载过程中,模块加载信息会顺利的往下持续打印出来,而在异常环境中会看到如下的输出内容:
…………
“aliim.exe”: 已加载“C:\WINDOWS\system32\oleaut32.dll”,未加载任何符号。
调试器:: 在进程加载过程中引发了未处理的无法继续的异常
程序“[4024] aliim.exe: 本机”已退出,返回值为 -1073741772 (0xc0000034)。
这里原本应该输出 ATL80.dll 加载成功的消息不再出现了,但是通过对比两次加载输出就能够知道加载失败的是 ATL80.dll,但是需要注意的是,WinSxS 下的 ATL80 版本不只一个,具体缺失的是哪一个可以通过打开 WinSxS 下的目录进行确定。
这是一种方法,但是在本机却不是那么有效的一种方法,因此在本机出现错误的时候我们甚至都没有机会能够比较正常过程中是怎样的情况。所以,这种方法实际上生效的场景是用于辅助解决远程机器上用户应用程序加载失败的模块定位。
方法二:有图有真相
实际上,这是一种更为有效和快捷,同时也更具普遍应用价值的方法,借助于 ProcMon 应用程序工具,可以比较容易地定位到问题所在。
ProcMon 可以用于监控应用程序的重要 API 活动过程并能清晰的列举出重要参数,只需简单的配置就能够锁定问题所在。
ProcMon 可以用于监控应用程序的重要 API 活动过程并能清晰的列举出重要参数,只需简单的配置就能够锁定问题所在。

ProcMon 配置

Result 列的 NAME NOT FOUND 指出了通过 CreateFile API打开失败的模块文件
Path 列指出了打开失败的文件名称
Leave a Reply
You must be logged in to post a comment.