什么是内存转储文件, 即dump?

======================

内存转储文件时一个进程或系统在某一给定的时间的快照. dump文件的种类有很多, 不同种类的dump文件包含不成程度的数据.

 

用户态内存转储文件 VS 内核态内存转储文件

======================

如果你抓一个进程的dump文件, 那么你抓取的是用户态的dump文件.

如果你抓取整个系统的内存dump文件, 那么你抓取的是内核态的dump文件.

一般来说, hung, crash, memory leak, exception的处理都不需要知道操作系统那段时间在做什么的, 所以抓取kernel dump浪费硬盘空间, 而且关于.net的debugging在内核态是几乎不可能的.

 

迷你DUMP(mini dump) VS 完整DUMP(full dump)

======================

通常, 大家对dump的分类是mini dumps 或 full dumps, 实际上这个概念有点不那么正确. full dump实际上是带有额外信息的mini dump.

 

Full Dump就是使用了/ma开关抓取了的dump文件, 这个开关意味着你抓取了如下的信息

  • 完整内存数据- full memory data
  • 句柄数据- handle data
  • 未加载的模块信息- unloaded module information
  • 基本内存信息- basic memory information
  • 模块信息- module information
  • 包括时间信息在内的线程和栈信息- thread and stack information including thread time information.

总之, 你会在一个文件中拿到比你想要的还多的信息.

 

Mini Dump是使用了/mdi开关抓取的dump文件, 这个开关意味着以下的信息会被抓取:

  • 模块- module
  • 线程- thread
  • 栈- stack
  • 栈上的指针引用的任何内存- any memory that is referenced by a pointer on a stack
  • 一些读写段- some read-write segments

这些东西大多会被用来查看dump文件被生成的时候, 线程正在执行什么. mini dump的尺寸一般只有几兆大小, 所以它的好处是它会被很快地被写好, 并且不占什么空间, 缺点是, 你不会得到多少关于.net的信息.

 

这里的开关指的是windbg.exe的.dump命令的开关.

 

另外, 当你运行引用程序崩溃的时候, 你会被询问是否要把错误信息发送给Microsoft, 那, 这种情况下你发送的就是mini dump, 没有什么personal的信息会被发送出去.

 

什么是SOS.dll

==================

讨论debugging托管进程而不提起SOS.dll是不可想象的. 你可以在Windbg和CDB中加载一些扩展组件, 它们会帮助你自动地完成一些你需要手动地完成的动作, 而这些动作中有一些是非常难以手工完成的, 比如说在非托管栈中建立器托管的栈. 这就是需要sos.dll的地方了.

 

你可以在你的debugger中的clr10目录下, 找到sos.dll.

 

你可以通过 !commandname 这样的方式来运行命令, 比如 !clrstack , 得到一个线程的托管栈.

 

完整的命令列表可以通过运行 !sos.help 命令来得到.