使用 WinDbg 分析 IIS CPU 100% 原因

作者:vkvi 来源:ITPOW(原创) 日期:2022-7-22

准备软件

打开 Microsoft Store,下载 WinDbg Preview 这款软件。

创建故障转储文件

打开“任务管理器”,打到 CPU 100% 那个 IIS 进程,右键,点击“创建转储文件”,约一会儿功夫,这个文件就创建好了,比如文件叫 w3wp.DMP。

分析

打开 WinDbg,将转储文件拖到 WinDbg 中。

1、在命令行输入 !runaway,查看哪个线程 CPU 运行时间最长。

WinDbg

如上,69 这个线程时间 9 分 38 秒,66 这个线程 9 分 8 秒,75 这个线程 9 分……IIS 中这么长的线程,确实太吓人了。

2、使用 ~69s 切换到 69 这个线程。

此时下面进度条会走,由于要到网上下载符号文件,所以要等一下,后面的步骤中,可能也会遇到这种情况,等就是了。

3、使用 !clrstack 查看具体的堆栈。

此时可能会出错:No export clrstack found。那就继续第 4 步。

4、使用 .load D:\dll\SOS.dll 加载 SOS。

这里说一个 SOS.dll 路径,通常是位于:

  • C:\Windows\Microsoft.NET\Framework\v2.0.50727

  • C:\Windows\Microsoft.NET\Framework\v4.0.30319

  • C:\Windows\Microsoft.NET\Framework64\v2.0.50727

  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319

具体以你实际的版本为路径,如果 IIS 与你的 WinDbg 不是同一台机器,也可以像我这样,将 IIS 上的 SOS.dll 复制到我本地的任一路径。

5、再执行 !clrstack

此时信息如下:

Failed to verify signature of file: C:\ProgramData\Dbg\sym\mscordacwks_AMD64_AMD64_2.0.50727.8806.dll\5C9C4C641ba000\mscordacwks_AMD64_AMD64_2.0.50727.8806.dll
Error code - 0x800B0100
Debugger.Settings.EngineInitialization.SecureLoadDotNetExtensions is enabled, set to false to disable.
dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.SecureLoadDotNetExtensions = false
CLRDLL: Consider using ".cordll -lp <path>" command to specify .NET runtime directory.
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of mscorwks.dll is 
                in the version directory
            3) or, if you are debugging a dump file, verify that the file 
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.

截图为:

SOS.dll

  • 点那个蓝色的。

  • 然后再执行:.cordll -ve -u -l

6、终于可以执行 !clrstack 了。

!clrstack

有了这种堆栈信息,找问题就不是问题了。

相关文章