使用 Windows Debugger 调试托管代码
使用 Windows Debugger 调试托管代码
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-managed-code
您可以使用 Windows debugger ( WinDbg、CDB 和 NTSD ) 来调试包含托管代码的目标应用程序。为了调试托管代码,你必须加载 SOS 调试扩展 (sos.dll) 和数据访问组件 ( mscordacwks.dll )。
Windows 调试器是与 Visual Studio 调试器分开的。关于更详细的在 Windows 调试器与 Visual Studio 调试器之间的区别,请参考:Windows Debugger。
托管代码入门
托管代码是与 Microsoft .NET 公共语言运行 (CLR) 时一起执行的。在托管代码应用程序中,编译器生成的二进制代码是微软中间语言 (MSIL),它是平台无关的。
当托管代码执行的时候,运行时生成平台特定的原生代码。从 MSIL 生成原生代码的过程被称为即时编译 (JIT)。在即时编译器将特定方法的 MSIL 编译之后,方法的原生代码保留在内存中。对该方法的随后无论何时的调用,都会执行原生代码,JIT 编译器将不再参与。
你可以使用多种编译器来构建托管代码。特别是,Microsoft Visual Studio 可以从多种不同的语言,例如 C#、VB、JScript 和支持托管扩展的 C++ 来构建托管代码。
CLR 并不是伴随着 .NET Framework 的升级而升级。例如,版本 2.0、3.0 和 3.5 的 .NET Framework 都使用 2.0 版本的 CLR。下表展示了每种 .NET Framework 所使用的版本和 CLR 文件名。
.NET Framework | CLR version | CLR 文件名 |
---|---|---|
1.1 | 1.1 | mscorwks.dll |
2.0 | 2.0 | mscorwks.dll |
3.0 | 2.0 | mscorwks.dll |
3.5 | 2.0 | mscorwks.dll |
4.0 | 4.0 | clr.dll |
4.5 | 4.0 | clr.dll |
调试托管代码
为了调试托管代码,调试器必须加载下面两个组件:
- 数据访问组件 (DAC) (mscordacwks.dll)
- SOS 调试扩展 (sos.dll)
注意:对于所有版本的 .NET Framework 来说,DAC 的文件名都是
mscordacwks.dll
,而 SOS 调试扩展的文件名则是sos.dll
。
获得 SOS 调试扩展 (sos.dll)
SOS 调试扩展 (sos.dll) 文件并不包含在当前版本的 Windows 调试工具中。
对于 .NET Framework 2.0 和以后的版本,sos.dll 包含在 .NET Framework 的安装中。
对于 .NET Framework 1.x 版本,sos.dll 不包含在 .NET Framework 的安装中。为了获得 .NET Framework 1.x 对应的 sos.dll,请下载 32 位版本的 Windows 7 调试工具 Windows 版本。
Windows 7 调试工具 Windows 版包含在 Windows SDK 的 Windows 7 版本中,可以从下面两个位置获得:
- Windows SDK for Windows 7 and .NET Framework 4.0
- Windows SDK for Windows 7 and .NET Framework 4.0 (ISO)
如果你运行在 64 位的 Windows 下,使用 该 ISO,以便指定你希望 32 位版本的 SDK,sos.dll 仅仅包含在 32 位版本的 Windows 7 调试工具中。
加载 mscordacwks.dll 和 sos.dll ( 现场调试 )
假设调试器和被调试的应用程序运行在同一台机器上。而应用程序所使用的 .NET Framework 也被安装在该计算机上,可以被调试器所使用。
调试器必须加载与托管代码应用程序所使用的 CLR 相同版本的 DAC。平台也必须匹配 ( 32 位或者 64 位 )。DAC (mscordacwks.dll) 来自 .NET Framework。为了加载正确的 DAC 版本,将调试器挂接到托管代码应用程序上,然后输入如下命令
.cordll -ve -u -l
输出应该与下面内容类似:
CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll
CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll
为了验证 mscordacwks.dll 的版本匹配应用程序所使用的版本,输入下面命令之一来显示当前加载的 CLR 模块。
- lmv mclr (for version 4.0 of the CLR)
- lmv mscorwks (for version 1.0 or 2.0 of the CLR)
输出应该类似下面:
start end module name
000007ff`26710000 000007ff`2706e000 clr (deferred)
Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
...
我机器上使用的另一个示例输出
0:000> lmv mclr
Browse full module list
start end module name
73db0000 74521000 clr (deferred)
Image path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Image name: clr.dll
Browse all global symbols functions data
Timestamp: Sat Apr 2 00:08:10 2022 (6247236A)
CheckSum: 00778D86
ImageSize: 00771000
File version: 4.7.3946.0
Product version: 4.0.30319.0
File flags: 8 (Mask 3F) Private
File OS: 4 Unknown Win32
File type: 2.0 Dll
File date: 00000000.00000000
Translations: 0409.04b0
Information from resource tables:
CompanyName: Microsoft Corporation
ProductName: Microsoft .NET Framework
InternalName: clr.dll
OriginalFilename: clr.dll
ProductVersion: 4.7.3946.0
FileVersion: 4.7.3946.0 built by: NET472REL1LAST_B
PrivateBuild: DDBLD305B
FileDescription: Microsoft .NET Runtime Common Language Runtime - WorkStation
LegalCopyright: Microsoft Corporation. All rights reserved.
Comments: Flavor=Retail
在前面的示例中,注意到 CLR (clr.dll) 的版本匹配 DAC (mscordacwks.dll) 的版本 : v4.0.30319。同时注意到它们的组件都是 64 位。
当你使用 .cordll
来加载 DAC 的时候,SOS 调试扩展 (sos.dll) 可能已经自动加载了。如果 sos.dll 没有自动加载,你可以使用下面的命令之一来加载:
- .loadby sos clr (for version 4.0 of the CLR)
- .loadby sos mscorwks (for version 1.0 or 2.0 of the CLR)
除了使用 .loadby
,你还可以使用 .load
。例如,加载 4.0 版的 64 位 CLR,你可以使用如下命令:
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll
在上面的输出中,注意 SOS 调试扩展 (sos.dll) 的版本匹配 CLR 的版本和 DAC 的版本:v4.0.30319。还要注意到所有的组件都是 64 位的。
加载 mscordacwoks.dll 和 sos.dll (dump 文件)
假设你使用调试器打开一个 dump 文件 (托管代码应用程序),它在其它计算机上被创建出来。
调试器必须加载该运行在其它计算机上的托管代码应用程序相同版本的 CLR 的 相同版本的 DAC。平台位数必须匹配 ( 32 位或者 64 位 ).
DAC ( mscordacwks.dll ) 来自 .NET Framework,但是我们假设你并没有正确版本的 .NET Framework 安装在运行调试器的计算机上。你可以有如下选择:
- 从符号服务器加载 DAC。例如,你可以包含 Microsoft 的公共符号服务器到你的符号路径中
- 安装正确版本的 .NET Framework 到运行调试器的计算机上
- 从创建该 dump 文件的人那里获得正确版本的 mscordacwks.dll ( 在其它计算机上 ),然后手工复制到运行调试器的计算机上。
这里说明一下 Microsoft 的符号服务器。
输入下面的命令
.sympath+ srv\* (Add symbol server to symbol path.)
!sym noisy
.cordll -ve -u -l
输入类似下面内容:
CLRDLL: Unable to get version info for 'C:\Windows\Microsoft.NET
\Framework64\v4.0.30319\mscordacwks.dll', Win32 error 0n87
SYMSRV: C:\ProgramData\dbg\sym\mscordacwks_AMD64_AMD64_4.0.30319.18010.dll
\5038768C95e000\mscordacwks_AMD64_AMD64_4.0.30319.18010.dll not found
SYMSRV: mscordacwks_AMD64_AMD64_4.0.30319.18010.dll from
https://msdl.microsoft.com/download/symbols: 570542 bytes - copied
...
SYMSRV: C:\ProgramData\dbg\sym\SOS_AMD64_AMD64_4.0.30319.18010.dll
\5038768C95e000\SOS_AMD64_AMD64_4.0.30319.18010.dll not found
SYMSRV: SOS_AMD64_AMD64_4.0.30319.18010.dll from
https://msdl.microsoft.com/download/symbols: 297048 bytes - copied
...
Automatically loaded SOS Extension
...
在上面的输出中,你可以看到调试器首先从本地计算机的 C:\Windows\Microsoft.NET
和符号缓存 (C:\ProgramData\dbg\sym) 中加载 mscordacwks.dll 和 sos.dll。当调试器不能在本地计算机上找到正确版本的该文件时,它通过公共符号服务器来获取它。
为了验证 mscordacwks.dll 的版本匹配应用程序所使用的版本,输入下面的命令来显示关于加载的 CLR 模块的信息。
lmv -mclr (for version 4.0 of the CLR)
lmv -mscorwks (for version 1.0 or 2.0 of the CLR)
输入应该类似:
start end module name
000007ff`26710000 000007ff`2706e000 clr (deferred)
Image path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
...
在上面的示例中,注意到 CLR (clr.dll) 的版本匹配 DAC (mscordacwks.dll) 的版本:v4.0.30319。并注意到组件都是 64 位的。
使用 SOS 调试扩展
为了验证调试器扩展已经正确加载,输入 .chain
命令:
0:000> .chain
Extension DLL search Path:
...
Extension DLL chain:
C:\ProgramData\dbg\sym\SOS_AMD64_AMD64_4.0.30319.18010.dll\...
...
dbghelp: image 6.13.0014.1665, API 6.2.6, built Wed Dec 12 03:02:43 2012
为了测试 SOS 扩展,输入 .help
命令。然后尝试 SOS 扩展所提供的命令之一。例如,你可以尝试 .DumpDomain
或者 .Threads
命令。
备注
有的时候,托管代码加载多于一个版本的 CLR。在这种场景下,你必须指定所加载的 DAC 版本。详细信息请参阅 .cordll
使用 Windows Debugger 调试托管代码的更多相关文章
- 使用Windows Debugger调试托管代码----引用自官方帮助文档
以下文字引用在Windbg的帮助文档.觉得对初次调试托管代码,非常有用,故粘贴至此. ========================================================= ...
- 深入理解Windows X64调试
随着64位操作系统的普及,都开始大力进军x64,X64下的调试机制也发生了改变,与x86相比,添加了许多自己的新特性,之前学习了Windows x64的调试机制,这里本着“拿来主义”的原则与大家分享. ...
- Windows Kernel Way 1:Windows内核调试技术
掌握Windows内核调试技术是学习与研究Windows内核的基础,调试Windows内核的方式大致分为两种: (1)通过Windbg工具在Windows系统运行之初连接到Windows内核,连接成功 ...
- windbg调试托管代码 .Net clr
现在很多的程序都是多语言混合编程的,比如我司的产品,就是用C++/.net clr混合编制的.那么当我们调试这样的程序时,一定要注意,比如有时我们只看到c++的栈和名称,而.net clr的代码确看不 ...
- windows本地调试安装hadoop(idea) : ERROR util.Shell: Failed to locate the winutils binary in the hadoop binary path
1,本地安装hadoop https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/ 下载hadoop对应版本 (我本意是想下载hadoop ...
- Windows程序调试系列: 使用VC++生成调试信息 转
Windows程序调试系列: 使用VC++生成调试信息 ZhangTao,zhangtao.it@gmail.com, 译自 “Generating debug information with Vi ...
- Windows服务调试状态下用Console启动
最近一直在用服务,发现服务也没有那么难调试. Windows服务调试状态下用Console启动:步骤分两步 第一步改Program,启动代码 static class Program { /// &l ...
- Windows服务调试小结(附Demo)
本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 阅读目录 介绍 搭建环境 调试方式 Demo下载 本文版权归mephisto和博客园共有,欢迎转载,但须 ...
- windows + myeclipse 调试 linux + tomcat 的java web服务 配置方式
一.linux tomcat配置和启动 1.catalina.sh第一行加入 declare -x CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt ...
- 修改Windows默认调试器
程序崩溃时,系统会弹窗让你选择是否进行调试,可以设置系统默认调试器. 注册表位置: HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVe ...
随机推荐
- 《Vue.js 设计与实现》读书笔记 - 第7章、渲染器的设计
第7章.渲染器的设计 7.1 渲染器与响应系统的结合 渲染器需要有跨平台的能力. 在浏览器端会渲染为真实的 DOM 元素. const { effect, ref } = VueReactivity ...
- 精彩回顾|【ACDU 中国行·杭州站】数据库主题交流活动成功举办!
8月19日下午,[ACDU 中国行·杭州站]在杭州西溪万怡酒店圆满落下帷幕.本次活动由中国数据库联盟(ACDU)联合墨天轮社区主办,蚂蚁集团 OceanBase 及亚信科技 AntDB 赞助支持.六位 ...
- Docker高阶篇(一)
本篇章主要为工作实践过程中对高端应用的处理和把控 1.Docker复杂安装 mysql的主从复制 https://www.bilibili.com/video/BV1gr4y1U7CY?p=41&am ...
- 一文搞定 KubeKey 3.1.1 离线部署 KubeSphere 3.4.1 和 Kubernetes v1.28
本文将详细介绍,如何基于操作系统 openEuler 22.03 LTS SP3,利用 KubeKey 制作 KubeSphere 和 Kubernetes 离线安装包,并实战部署 KubeSpher ...
- 【速记】C++ STL自定义排序
因为是"速记",难免会有不完善的地方.这篇笔记咱日后应该还会进行补充. 关于sort的比较函数 void sort( RandomIt first, RandomIt last, ...
- Typecho框架个人博客搭建方法学习
使用Typecho框架一个月又十二天了,就目前感觉来说,整体还不错,很多方面都支持个性化,二次开发,但是目前MD编辑器有一丢丢问题,不能同步滚动条滚动,就是编辑器区域滚动,预览区域没有动静,需要两边都 ...
- 【CoCollider】让系统和应用适配如此简单
在各平台应用开发过程中,随着业务的功能增加,不免会涉及到非公开的API依赖,针对某些应用或厂商系统的适配,每个版本都需要投入精力去排查,CoCollider 可以让我们的适配效率从几个星期提升到几小时 ...
- CSP模拟58联测20 T3 注视一切的终结
CSP模拟58联测20 T3 注视一切的终结 题面及数据范围 Ps:链接为衡水中学OJ. 去除重边以后是树,而我们需要使一个点到另外一个点的简单路径上相邻边的颜色尽可能不相同. 发现如果一条边有 \( ...
- MySQL原理简介—1.SQL的执行流程
大纲(2426字) 1.MySQL驱动的作用 2.Java系统中的数据库连接池的作用 3.MySQL中的数据库连接池的作用 4.网络连接必须让线程来处理 5.SQL接口会负责处理接收到的SQL语句 6 ...
- 在table中,tbody没有充满整个table
解决方法就是给table加上 display:table;就好了