本书是第一本关注于追踪当今最复杂的和最有挑战性的.NET应用程序Bug的实用指南。它完整地介绍了使用最强大的本地调试工具,包括WinDBG、NTSD、和CDB来调试.NET应用程序。通过这些工具,作者介绍了如何识别引发问题的根本原因,这比使用其他调试工具发现问题要快很多。
首先,本书介绍了成功地使用.NET本地调试器所需的关键概念。接下来,介绍了高级的调试技巧,使用真实世界的例子来说明很多常见的C#编程错误。
本书是畅销图书《Windows高级调试》的姊妹篇。本书作者也是《Windows高级调试》的作者。
.NET高级调试
Advanced .NET Debugging
封面:
畅销书《Windows高级调试》
姊妹篇
.NET调试权威参考书
涉及.NET CLR 4.0最新调试功能
(美) Mario Hewardt 著
聂雪军 等译
封底:
“对于任何一个.NET开发人员来说,本书都具有极高的参考价值。它包含了许多调试技巧以及CLR内部工作机制的细节,这对于设计软件架构的开发人员来说是非常有益的。”
—— Jeffrey Richter,Wintellect公司顾问、培训师和作者
“这是Mario推出的又一本好书。他之前著的《Windows高级调试》(与Daniel Pravat合著)对于非托管代码的调试来说是一本不可多得的参考书,而本书同样具有极高的质量,阐述清晰并且探讨深入,因此对于.NET调试来说同样具有帮助作用。”
—— Mark Russinovich,微软公司技术顾问
这是分析.NET应用程序问题方面的一本全面且实用的参考书。
本书首次专门且系统地介绍了如何分析当前最复杂和最具挑战性的.NET应用程序问题。这是一本介绍如何通过非托管调试器(包括WinDBG、NTSD和CDB等)来调试.NET应用程序的书籍。作者详细阐述了如何借助这些工具找出问题的真实原因——这比使用其他任何调试器都将节省大量的调试时间。
作者首先介绍了在使用.NET非托管调试器时的一些关键概念。接下来介绍了许多巧妙的调试技术,并且通过真实的示例来展示各种常见的C#编程错误。
读者在本书中可以学到:
使用事后调试技术,包括PowerDBG以及其他“强大的调试工具”。
理解在.NET CLR 4.0中包含的新调试功能以及与之前版本的差异。
掌握对Windows调试工具集、SOS、SOSEX、CLR分析器以及其他调试工具的使用。
深入理解CLR内部工作机制,例如分析线程特定的数据、托管堆和垃圾收集器、互用层以及.NET异常等。
解决一些复杂的同步问题、托管堆问题、互用性问题等。
如何生成和分析崩溃转储。
配套网站(advanceddotnetdebugging.com)上包含了所有的示例代码、程序等。
作者简介
Mario Hewardt 是微软公司的一位资深开发经理,在Windows系统级开发领域拥有十余年的开发经验。他目前领导开发团队负责Microsoft在线IT管理解决方案的开发。Hewardt是《Windows高级调试》(机械工业出版社2009年5月出版)的作者之一。
自从2007年底写完《Windows高级调试》(由机械工业出版社于2009年5月出版——译者注)一书后,许多读者都来信希望我再写一本关于.NET调试的书籍。最初在《Windows高级调试》中确实包含了一章内容专门介绍.NET调试,但最终还是去掉了这章,因为我认为,仅有一章的篇幅无法涵盖.NET调试的所有内容,这给读者带来的只能是更多的疑问而不是启迪。.NET已经成为众多开发人员的首选平台。根据统计数据表明,使用C#的开发人员与使用C++的开发人员在数量上基本相当。要想在.NET开发中取得成功,那么就需要知道如何正确地应对在开发中遇到的各种问题和挑战。
为什么在一本介绍.NET调试的书中使用了WinDBG、NTSD以及CDB等这些调试器?显然还有其他的调试器可以使用(有些调试器甚至有着更高的用户友好性)。初看上去,使用非托管调试器似乎有些棘手,但如果将它们的功能完全发挥出来,那么在分析一些复杂的问题时将节约大量的时间。部分原因是当使用非托管调试器时,更容易收集CLR本身(即.NET运行时)的关键内部信息,并可以根据这些信息来分析问题的原因。这些信息包括垃圾收集器、互用性层、同步原语等。这种信息不仅会在许多调试任务中起到关键作用,而且还是一种很好的学习资料,因为它给出了对运行时架构的详细描述。最后,在某些情况下(随着目前 “互联”解决方案越来越多),需要使用一种零痕迹(ZEOR foot print)调试器。这种“更友好的”调试器通常需要在本地进行安装,在这个过程中将把所需的二进制文件复制到目标机器上,并在系统的不同位置保存配置信息等。如果在某台机器上不允许修改配置信息(例如在用户机器或者数据中心的机器上),那么唯一可行的方法就是使用非托管调试器,因为这种调试器不需要修改配置信息。
本书弥补了调试领域中的这种缺陷,并重点介绍了如何在CLR环境中发挥非托管调试器的功能。本书采用了与实践紧密相结合的讲解方式,使用真实的调试任务示例,以确保读者不仅可以学习书中介绍的内容,而且还能获得实际的体验。我希望读者在阅读本书时获得的乐趣与我在写这本书时获得的乐趣一样。
本书的目标读者
如果在分析问题时知道该采用哪些工具,并且知道如何对不同的问题进行分类,那么通常可以开发出高质量的软件产品,并降低在技术支持上的开销。然而,尽管我们已经竭尽全力消除产品中的错误,但在客户机器上仍然会冒出一些意料之外的问题,只有知道如何在这种情况下分析这些问题,才能有效地避免给客户造成麻烦或者停机。所有的软件工程师都有必要了解在各种不同的环境中应该使用哪些工具来分析问题。如果掌握了调试的技巧,那么产品质量将得到极大提升,而且公司的形象也会由于软件的高质量和高可靠性而得到提升。
软件开发工程师
我曾看到许多开发人员努力解决各种复杂的错误,并且最终花费数天(有时候甚至是数星期)时间来缩小问题的范围以及找到问题的根源。在大多数时候,我都会询问开发人员使用了哪些工具。得到的答案通常大同小异:反复进行代码审查和跟踪,直至最终找出问题。代码审查和有针对性的跟踪对于分析错误来说固然重要,但它们通常也是非常耗时的。面对现实吧!假使我们能够获得在分析代码问题时需要的所有信息,那么将不需要使用调试器。然而,实际情况是,在某些情况中仅凭代码跟踪不足以解决问题,而是需要将调试器附载到出现问题的进程上。 在许多时候,当我告诉开发人员某个工具可以极大地降低某种问题的分析时间后,开发人员会吃惊地发现居然有这种工具存在。
本书的目标读者之一就是那些在.NET平台上编写代码以及分析复杂问题的开发人员。能够深入地理解哪些工具可以帮助开发人员找出一些复杂且耗时的问题,对于产品的成功来说非常重要。在开发过程中,知道使用哪些工具以及启动哪些配置,对于获得成功来说是非常关键的。
质量保证工程师
质量保证(Quality Assurance,QA)的目的是找出开发人员在代码中出现的问题。详细的测试计划以及完全自动化的测试流程都能使质量保证工程师们以高效的方式来测试各个组件。正如了解调试工具和配置信息对开发人员非常重要,这对于质量保证工程师也同样重要。在测试过程中,他们可能会遇到各种问题,如果在测试过程中能使用正确的工具,那么将帮助他们以及开发人员在解决问题上节约大量的时间。如果在进行测试时没有使用正确的工具,那么在重新启动测试流程(并且打开这个工具)时可能最终发现这不是一个可重现的问题。在本书中介绍的调试器和工具能够提高质量保证工程师的工作效率,并且帮助整个产品团队更快地获得结果。
产品支持工程师
产品支持工程师面临的情况与软件开发工程师和质量保证工程师遇到的情况非常相似。关键的区别在于他们所处的环境不同。他们不仅要解决客户的问题,而且经常必须面对来自多个地方的代码(即不仅仅是产品的代码)。此外,产品支持工程师通常只能使用进程的静态快照,而无法进行实时调试,这就使得找到问题的根源更加困难。在这些情况下,如果知道如何使用调试器以及相应的工具,那么就不需要多次往返于公司与客户之间(这不仅会带来很高的成本开销,而且很容易令人沮丧),并且能够立即解决问题。
运行工程师
随着越来越多的软件移动到云中(一种基于服务的提供方式),越来越多的代码是在专门的数据中心运行,而不是在客户的机器上运行。负责这些服务正常运行的工程师们就被称为运行工程师。运行工程师面临的关键挑战之一是,要解决所有使服务无法最优化运行的问题。通常,这意味着要尽快地解决问题。如果运行团队无法解决某个问题,那么产品团队会参与进来,这将是一个耗时的过程,因为产品团队可能要反复地指导运行团队分析这个问题。通过使用正确的工具,运行团队可以解决遇到的大部分问题,而无需将这些问题提交给产品团队,因此节约了双方的时间;并且最重要的是,客户在使用服务时遇到的停机时间也将更短。
预备知识
虽然本书介绍的是如何使用非托管调试器,但重点在于介绍如何调试.NET代码,而不是非托管调试的一些基本步骤。第3章将会简要介绍一些主题,例如如何将调试附载到目标进程,设置符号路径以及设置断点等,但并没有给出详细介绍。关于非托管调试器以及非托管代码调试的进一步介绍可以参考我之前写的一本书:Mario Hewardt和Daniel Pravat,《Advanced Windows Debugging》, Boston,MA:AddisonWesley,2007。1中文版为《Windows高级调试》,由机械工业出版社于2009年5月出版。——译者注
此外,还需要深入理解C#,因为所有的示例代码都是采用C#编写的。 在学习C#时可以使用下面这本书:Mark Michaelis,《Essential C# 20》, Boston, MA: AddisonWesley, 2006。
虽然读者需要预先具备C#的知识,但并不需要深入了解CLR。本书不仅介绍了如何调试.NET程序,还对.NET平台中大量的核心代码给出了详细解释,这些信息是获得调试成功的重要基础。
本书的组织结构
本书分为三个部分,下面介绍每一部分包含的内容。
第一部分简介
这一部分包含的内容主要是介绍如何使用非托管调试器来调试.NET的基础知识。介绍的主题包括:需要使用的工具、对MSIL的介绍、基本的调试任务等,我对这些主题都进行了全面的分析和阐述。如果你是第一次了解这些调试器,那么建议你按照先后顺序阅读这些内容。
第1章调试工具简介
这一章对本书中使用的工具给出了简要介绍,包括应用场合、下载位置以及安装方法等。所介绍的工具包括:Windows调试工具集、SOS、SOSEX、CLR分析器等。
第2章CLR基础
这一章介绍了.NET 运行时的核心基础。首先介绍了主要的运行时组件,然后是一些相关主题,包括程序集的加载、运行时元数据等。其中使用非托管调试器和工具来说明运行时的内部工作机制。
第3章基本调试任务
这一章介绍了在使用非托管调试器调试.NET程序时的一些最常见调试任务,此外还介绍了一些其他主题,例如查看线程数据、垃圾收集器堆、.NET异常以及事后调试的基本概念等。
第二部分调试实践
第二部分是本书的核心内容,介绍了主要的CLR组件以及如何分析与这些组件相关的常见问题。在这部分每一章的开始,首先给出组件的概述,并通过调试器来说明关键概念。之后给出使用这个组件时会出现的常见编程错误。接下来详细介绍了在解决这些错误时该采取的思路,并给出了直观的调试会话。第二部分中的各章可以按照任意顺序来阅读,因为每一章都是针对某个特定组件的问题进行讨论。
第4章程序集加载器
.NET程序既可以是简单的命令行程序,也可以是复杂的多进程/多机器服务器程序,其中包含了大量程序集的相互协作。要想高效地调试.NET程序中的问题,你必须仔细地理解各个.NET程序集之间的依赖性。这一章介绍了CLR程序集加载器的工作原理,以及在使用这个组件时最常见的问题。
第5章托管堆与垃圾收集
虽然.NET开发人员可以坐享自动内存管理机制带来的好处,但仍然需要小心地避免一些高开销的错误。 CLR垃圾收集器是一个自动的内存管理器,它使开发人员可以更少关注内存管理,而更多关注程序逻辑。尽管CLR负责为开发人员管理内存,但仍然要小心地避免一些可能对程序造成严重破坏的陷阱。在这一章中,我们将看到垃圾收集器的工作机制,学会观察垃圾收集器的内部信息以及与自动垃圾收集操作相关的一些常见编程错误。
第6章同步
多线程的环境包含了大量的灵活性和高效因素。然而,伴随这种灵活性的是线程管理中的复杂性。为了避免在程序中出现高开销错误,我们必须小心地确保线程以一种相互协作的方式来执行工作。这一章介绍了.NET中的同步原语,并介绍了如何使用调试器和工具来分析常见的线程同步问题。此外还介绍了死锁以及线程池等问题。
第7章互用性
.NET非常依赖底层的Windows组件。为了调用非托管的Windows组件,CLR公开了两种主要的互用性方法:
平台调用
COM互用性
由于.NET和Win32编程模型非常不同,因此一些编程习惯经常会导致难以跟踪的问题。在这一章中,我们将看到一些在使用互用性时常见的错误,以及如何使用调试器和工具来分析这些错误。
第三部分高级主题
这一部分介绍的主题包括:事后调试、一些功能强大的调试工具,以及.NET 40中的新功能。
第8章事后调试
通常,我们可能无法获得对故障机器的完全访问权限,因此无法对客户产品机器上出现的错误进行实时调试。本章介绍了如何在不需要访问物理机器的情况下对问题进行调试。讨论的主题包括:崩溃转储的基本知识,如何生成以及分析崩溃转储文件等。
第9章一些功能强大的调试工具
在.NET调试过程中,除了一些“标准的“工具外,还有其他一些功能强大的调试工具。这一章为读者介绍了这些强大的工具,例如owerDBG(通过PowerShell调试)以及其他工具。
第10章CLR 40
随着CLR 40的即将发布,这一章将简要介绍CLR 40中的新增功能。此外,本章依次介绍了之前内容中每个主题在CLR 40中的不同之处。
排版约定
在本书的示例中给出了大量的调试输出。调试输出是指用户在执行某个动作后调试器显示的结果。通常,这种调试输出包含了以简洁形式给出的信息。为了引用这些数据并使读者更容易阅读,在调试输出中采用了粗斜体。此外,在调试输出中的粗体内容表示需要键入的命令。在接下来的示例中说明了这些字体。
在这个示例中,需要在调试会话中键入~*kb。在键入这个命令后,将输出几行信息,其中最关键的就是0007fd30。接下来应该键入dd 0007fd30命令,这个命令将显示之前高亮数值0007fd30的更多信息。在本书中使用的所有工具都是从安装文件夹中启动的。例如,如果Windows调试器安装到文件夹C:\\Program Files\\Debugging Tools for Windows中,那么启动windbg.exe的命令行如下所示:
所需工具
在本书中使用的所有工具都可以免费下载。在第1章中给出了在本书中使用的工具及其下载地址。
示例代码
要说明如何调试存在问题的代码,最有效的方式就是使用实际的示例。然而,在一本书中包含完整的示例代码是不现实的,因为这将使我们无法以简洁的方式说明问题。因此,对本书中的示例代码都进行了简化(但并不影响完整性)。所有的示例代码都是基于C#和.NET 20编写的。每个示例都可以从本书的Web站点下载,地址为http://www.advanceddotnetdebugging.com。每个示例都包含了一个MSBuild项目文件。MSBuild是一个功能完备的命令行构建环境,与.NET SDK 20一起发行,并且与Microsoft Visual Studio是兼容的。所有的调试会话都是基于32位版本的.NET框架。
技术支持
虽然我努力避免在本书中出现错误,但还是不可避免地存在一些疏漏。你可以将发现的错误提交到本书的网站http://www.advanceddotnetdebugging.com或者可以直接给我写信,电子邮件地址为marioh@advanceddotnetdebugging.com。在这个网址上还包括一个勘误表以及相应的错误和修正。
小结
在当前复杂的软件解决方案中,无论是独立的命令行程序还是高度互连并且在全世界范围内通信的系统,都会存在代码问题。要确保在这些产品中不出现错误似乎是一项很艰难的任务,但只要有正确的工具以及知道如何使用这些工具,那么软件工程师的工作就会变得很轻松。这些强大的工具和正确的思路不仅有助于使分析问题的过程变得更高效,而且还为企业节省了大量的财力和减少了可能造成的客户流失。本书的目的是为了使软件工程师们获得.NET调试的知识和经验,从而避免一些严重的陷阱,并且使问题的分析过程变得更为高效和成功。
欢迎阅读。
致谢
基于之前编写《Windows高级调试》一书的经验,我很清楚地认识到当一边在微软全职工作,一边在业余时间写书时需要付出多大的努力。在《Windows高级调试》一书获得成功后,读者不断要求我再写一本关于.NET和CLR调试的书,因此我决定再次迎接挑战。虽然与第一本书相比,这次的任务要更容易一些,但仍然付出了很大的努力——不仅仅是我自己,而且还包括本书中从构思到出版过程中参与的许多人。
首先,我要感谢我的家人。我的妻子Pia不仅毫无怨言地容忍我经常说“这个周末我要写作”,而且在2008年底为我带来了漂亮可爱的女儿Gemma。如果没有Pia和Gemma的耐心、支持和鼓励,本书是无法完成的。
感谢AddisonWesley团队,他们对一位在业余时间写作的作者再次给予了难以置信的宽容。我的团队成员经常不得不请求修改时间表,提供高质量的编辑过程并且加速出版计划,以便使读者能尽快看到这本书。特别要感谢Joan Murray,感谢他使得整个过程极为顺畅,感谢Chris Zahn仔细审阅和纠正我的英语表述,感谢Olivia Basegio在Joan度假时负责接管编辑工作。此外,特别感谢Curt Johnson为本书所做的市场推广工作。
当然, 无论作者如何小心,总会有些技术细节不能准确把握。因此,如果有一群优秀的工程师来审阅本书的内容,那么对于一本书的成功无疑是非常重要的。在本书的编写过程中,我很荣幸与一些优秀的工程师们共事(大多数都在.NET部门工作),他们提出了极有见地的反馈和建议,并回答了许多常见的问题。真诚地感谢Mark Russinovich、 Maoni Stephens、Roberto Farah、Tess Ferrandez、Lee Culver、Pat Styles、Eric Eilebrecht、Steve Johnson以及Jon Langdon。
感谢Patrick Dussud,他不仅非常细致地审阅了本书的手稿,而且还为本书作序。如果没有他的贡献,本书不会是大家现在看到的这样。
同样感谢Easy Web Launch (www.easyweblaunch.com)的Alexandra H.Anderson,感谢他为本书提供了网页。
最后,我想要感谢这么多年来为我提供反馈意见的所有读者。你们的支持使本书得以完成。
计算机\程序设计
“对于任何一个.NET开发人员来说,这本书都具有极高的参考价值。它包含了许多调试技巧以及CLR内部工作机制的细节,这对于设计软件架构的开发人员来说是非常有益的。”
——Jeffrey Richter,Wintellect公司顾问、培训师和作者
“这是Mario推出的又一本好书。他之前著的《Windows高级调试》(与Daniel Pravat合著)对于非托管代码的调试来说是一本不可多得的参考书,而本书同样具有极高的质量,清晰的阐述以及深入的探讨,因此对于.NET调试来说同样极有帮助作用。”
——Mark Russinovich,微软公司技术顾问
这是分析.NET应用程序问题方面的一本全面且实用的参考书。
本书首次专门且系统地介绍了如何分析当前最复杂和最具挑战性的.NET应用程序问题。这是一本介绍如何通过非托管调试器(包括WinDBG、NTSD和CDB等)来调试.NET应用程序的书籍。借助这些工具,作者详细阐述了如何找出问题的真实原因——这比使用其他任何调试器都将节省大量的调试时间。
作者首先介绍了在使用.NET非托管调试器时的一些关键概念。接下来介绍了许多巧妙的调试技术,并且通过真实的示例说明如何调试各种常见的C#编程错误。
读者在本书中可以学习到
* 如何使用事后调试技术,包括PowerDBG以及其他“强大的调试工具”
* 理解在.NET CLR 4.0中包含的新调试功能以及与之前版本的差异
* 掌握对Windows调试工具集、SOS、SOSEX、CLR分析器以及其他调试工具的使用
* 深入理解CLR内部工作机制,例如分析与线程特定的数据、托管堆和垃圾收集器、互用层以及.NET异常等
* 解决一些复杂的同步问题、托管堆问题、互用性问题等
* 如何生成和分析崩溃转储
配套网站(advanceddotnetdebugging.com)上包含了所有的示例代码、程序等。
(美) Mario Hewardt 著:暂无简介
聂雪军 等译:暂无简介
本书是Mario Hewardt继《Windows高级调试》之后推出的又一部力作。.NET框架为开发人员隐藏了底层系统的复杂性,例如自动化内存管理机制使得开发人员无须关心内存的释放与回收,从而极大地提升软件开发效率。然而,这种抽象也使得一些问题调试起来更为困难,因此需要了解的底层技术细节也变得更多。本书以非托管调试器(包括WinDBG、NTSD和CDB)为基础,详细介绍了.NET框架中关键组件的运作原理及其与.NET应用程序中一些常见问题的关联,并通过丰富的示例来阐述在调试不同问题时所应采取的策略、步骤以及工具。
作为《Windows高级调试》的姊妹篇,本书的目的同样是为了将一些有价值的调试思路和调试工具推荐给软件开发人员,以提高开发人员的调试效率。本书的特点主要有:
深入介绍了.NET中关键组件的内部运作原理,包括CLR垃圾收集器、程序集加载器、应用程序域以及类型元数据等。在调试.NET应用程序时,对.NET内部运行机制了解得越清楚,就越能控制程序的运行状态,调试效率也就越高,这与调试Windows系统应用程序或者其他任何类型程序的道理是相通的。
通过丰富的示例来讲解调试过程。本书分析了.NET应用程序在程序集加载、托管堆、同步以及互用性等方面的一些常见问题。对于每类问题,作者首先给出了问题的外在表现,然后介绍如何做出合理假设以及采用相应的调试策略来进行验证,并最终找出问题的根源。对调试过程中的每个步骤,作者都给出了非常清晰的讲解和分析,使得读者更容易掌握书中内容。
重点介绍了两个调试器扩展SOS和SOSEX。在本书各章的内容中穿插对SOS与SOSEX中各个命令的介绍,包括命令的语法格式、应用场合以及使用技巧等。这些内容在其他书籍中是很少出现的。
此外,本书还给出了一些高级调试主题,包括崩溃转储文件的生成、事后调试,并介绍了一些辅助调试工具,例如PowerDbg和CLR分析器等。这些内容都为开发人员调试复杂问题提供了必要的基础知识。在最后一章还介绍了在.NET 40中引入的一些新功能。
本书保持了《Windows高级调试》的行文风格与内容组织方式,围绕核心的调试思路,采用了由浅入深、由表及里的讲解方式,并辅以丰富的示例和详细的分析,使读者逐步掌握.NET应用程序的调试技巧。本书的技术性较强,需要读者对.NET框架的底层架构和组件有一定的了解,并且具备一定的C#编程基础。作者Mario Hewardt是微软公司的资深工程师,他在调试领域已经工作了十余年。本书汇聚了作者多年来的调试实践经验,对于.NET开发人员来说是一本不可多得的参考手册。
参与本书翻译工作的还有李杨、吴汉平、徐光景、童胜汉、陈军、胡凯、刘红、张玮、陈红、李斌、李勇涛、王海涛、周云波、彭敏才和张世锋等。由于译者的水平和时间有限,翻译中的疏漏和错误在所难免,还望读者和同行不吝指正。
聂雪军
2010年8月于武汉
对本书的赞誉
译者序
序
前言
关于作者
第一部分简介
第1章调试工具简介1
11Windows调试工具集1
12NET 20 可再发行组件2
13NET 20 SDK3
14SOS5
15SOSEX7
16CLR分析器8
17性能计数器9
18NET反编译器11
19PowerDbg11
110托管调试助手12
111小结15
第2章CLR基础16
21高层概览16
22CLR和Windows加载器18
221加载非托管映像19
222加载.NET程序集21
23应用程序域24
231系统应用程序域27
232共享应用程序域27
233默认应用程序域27
24程序集简介27
25程序集清单29
26类型元数据30
261同步块表36
262类型句柄40
263方法描述符45
264模块47
265元数据标记49
266EEClass50
27小结52
第3章基本调试任务53
31调试器以及调试目标53
32符号57
33控制调试目标的执行59
331中断执行59
332恢复执行60
333单步调试代码62
334退出调试会话65
34加载托管代码调试的扩展命令66
341加载SOS调试器扩展66
342加载SOSEX调试器扩展69
35控制CLR的调试69
36设置断点69
361在JIT编译生成的函数上设置断点72
362在还没有被JIT编译的函数上设置断点74
363在预编译的程序集中设置断点76
364在泛型方法上设置断点79
37对象检查80
371 内存转储82
372值类型的转储84
373转储基本的引用类型90
374数组的转储91
375 栈上对象的转储96
376找出对象的大小98
377异常的转储98
38线程的操作102
381ClrStack103
382Threads106
383DumpStack109
384EEStack111
385COMState111
39代码审查112
391反汇编代码112
392从代码地址上获得方法描述符113
393显示中间语言指令114
310CLR内部命令115
3101获得CLR的版本115
3102根据名字找到方法描述符115
3103对象同步块的转储116
3104对象方法表的转储116
3105托管堆和垃圾收集器信息的转储116
311诊断命令117
3111找出对象的应用程序域117
3112进程信息117
312SOSEX扩展命令118
3121扩展的断点支持119
3122托管元数据122
3123栈回溯123
3124对象检查124
3125自动死锁检测125
3126托管堆与垃圾收集命令126
313崩溃转储文件128
314小结130
第二部分调 试 实 践
第4章程序集加载器131
41CLR加载器简介131
411程序集标识132
412全局程序集缓存135
413 默认加载上下文137
414指定加载上下文138
415无加载上下文139
42简单的程序集加载故障139
43加载上下文故障144
44互用性与DllNotFoundException153
45轻量级代码生成的调试154
46小结158
第5章托管堆与垃圾收集159
51Windows内存架构简介159
52垃圾收集器的内部工作机制167
521代168
522根对象175
523终结操作181
524回收GC内存189
525大对象堆190
526固定195
527垃圾收集模式200
53调试托管堆的破坏问题200
54调试托管堆的碎片问题207
55小结230
第6章同步231
61同步的基础知识231
62线程同步原语231
621事件235
622互斥体237
623信号量238
624监视器239
625读写锁 240
626线程池241
63同步的内部细节241
631对象头242
632同步块243
633瘦锁246
64同步任务249
641死锁249
642孤立锁:异常256
643线程中止261
644终结器挂起264
65小结271
第7章互用性272
71平台调用272
72COM 278
73P/Invoke调用的调试282
731调用约定282
732委托286
74互操作中内存泄漏问题的调试293
75COM互用性中终结操作的调试298
76小结306
第三部分高 级 主 题
第8章事后调试307
81转储文件基本知识308
811通过调试器来生成转储文件309
812通过ADPlus生成转储文件314
813转储文件的调试316
814数据访问层317
815转储文件分析:未处理的.NET异常319
82Windows错误报告320
83小结344
第9章一些功能强大的调试工具345
91PowerDbg345
911安装PowerDbg345
912AnalyzePowerDbgThreads347
913SendPowerDbgCommand348
914扩展PowerDbg的功能350
92Visual Studio352
921SOS的集成352
922.NET框架源代码级调试355
923Visual Studio 2010358
93CLR分析器361
931运行CLR分析器362
932Summary视图363
933Histogram视图364
934Graph视图366
94WinDbg和CmdTree命令367
95小结368
第10章CLR 40369
101工具369
1011Windows调试工具集369
1012.NET 40可再发行组件369
1013SOS370
102托管堆与垃圾收集370
1021扩展的诊断信息370
1022后台垃圾收集374
103同步375
1031线程池与任务375
1032监视器376
1033栅栏377
1034CountdownEvent377
1035ManualResetEventSlim377
1036SemaphoreSlim377
1037SpinWait和SpinLock377
104互用性378
105事后调试379
106小结379