搜档网
当前位置:搜档网 › 使用Windbg生成dump文件

使用Windbg生成dump文件

使用Windbg生成dump文件WinDBG
2010-10-21 23:19:50 阅读145 评论0 字号:大中小 订阅
Windbg生成dump文件的方法:

程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件。 步骤:

1) 打开WinDBG并将之Attach 到crash的程序进程

2) 输入产生dump 文件的命令

WinDBG产生dump 文件的命令是 .dump ,可以选择不同的参数来生成不同类型的dump文件。

选项(1): /m

命令行示例:.dump /m C:\dumps\myapp.dmp

注解: 缺省选项,生成标准的minidump, 转储文件通常较小,便于在网络上通过邮件或其他方式传输。 这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、 进程信息和线程信息。

选项(2): /ma

命令行示例:.dump /ma C:\dumps\myapp.dmp

注解: 带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,但如果条件允许(本机调试,局域网环境), 推荐使用这中dump。

选项(3):/mFhutwd

命令行示例:.dump /mFhutwd C:\dumps\myapp.dmp

注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案。



--------------------------------------------------------------------------------
1.为什么需要dump 内存
系统经常出现各种各样的问题,这些问题,可能是本身程序设计的时候考虑的不够周全,导致的程序异常,或者系统本身的问题。那么,当系统crash或者发生exception的时候,如何获得系统的context,然后给出准确地diagnostics,然后提出resolution呢?
我们所说的crash或者exception包括各种各样的情况,比如系统某个进程占用大量资源,某个进程low performance,某个程序crash等等。为了获得发生crash或者exception的process的context, 我们必须得到发生exception的时候,该process的context。那么可以给该process进行捕捉一个snapshot。捕捉发生exception时刻的snapshot所用的方法就是dump当时该process的内存。

2.dump内存的方法
这里介绍一种dump内存的方法,就是windbg中的.dump。当程序发生异常时,我们可以通过该方法snapshot该process在发生exception的时候的context。
具体做法就是:
当program发生exception的时候,或者发生之前,我们可以将windbg attach to a specific process in which en exception will occur. 然后在windbg command window中,type g or press F5 to let the program execute.如果不出意外的话,会出现exception,然后我们我们可以用.dump command来capture the snapshot。the following section is the usage about command .dump.

.dump (Create Dump File)
The .dump c

ommand creates a user-mode or kernel-mode crash dump file.



Syntax
.dump Options FileName
.dump /?


Parameters
Options
Represents one or more of the following options
/o
Overwrites an existing dump file with the same name. If this is option not used and the there is a file with the same file name, the dump file is not written.
/f
(Kernel mode:) Creates a complete memory dump.
(User mode:) Creates a full user-mode dump. Despite their names, the largest minidump file actually contains more information than a full user-mode dump. For example, .dump /mf or .dump /ma creates a larger and more complete file than .dump /f. In user mode, .dump /m[MiniOptions] is always preferable to .dump /f.

/m[MiniOptions]
Creates a small memory dump (in kernel mode) or a minidump (in user mode). If neither /f nor /m is specified, /m is the default.
In user mode, /m can be followed with additional MiniOptions specifying extra data that to be included in the dump. If no MiniOptions are included, the dump will include module, thread, and stack information, but no additional data. You can add any of the following MiniOptions to change the contents of the dump file; they are case-sensitive.

MiniOption Effect
a Creates a minidump with all optional additions. The /ma option is equivalent to /mfFhut — it adds full memory data, handle data, unloaded module information, basic memory information, and thread time information to the minidump.
f Adds full memory data to the minidump. All accessible committed pages owned by the target application will be included.
F Adds all basic memory information to the minidump. This adds a stream to the minidump that contains all basic memory information, not just information about valid memory. This allows the debugger to reconstruct the complete virtual memory layout of the process when the minidump is being debugged.
h Adds data about the handles associated with the target application to the minidump.
u Adds unloaded module information to the minidump. This is available only in Windows Server 2003 and later versions of Windows.
t Adds additional thread information to the minidump. This includes thread times, which can be displayed by using the !runaway extension or the .ttime (Display Thread Times) command when debugging the minidump.
i Adds secondary memory to the minidump. Secondary memory is any memory referenced by a pointer on the stack or backing store, plus a small region surrounding this address.
p Adds process environment block (PEB) and thread environment block (TEB) data to the minidump. This can be useful if you need access to Windows system information regarding the application's processes and threads.
w Adds all committed read-write private pages to the minidump.
d Adds all read-write data segments within the executable image to the minidump.
c Adds code sections within images.
r Deletes from the minidump those portions of the stack and store memory

that are not useful for recreating the stack trace. Local variables and other data type values are deleted as well. This option does not make the minidump smaller (because these memory sections are simply zeroed), but it is useful if you want to protect the privacy of other applications.
R Deletes the full module paths from the minidump. Only the module names will be included. This is a useful option if you want to protect the privacy of the user's directory structure.



These MiniOptions can only be used when creating a user-mode minidump. They should follow the /m specifier.

/u
Appends the date, time, and PID to the dump file names. This ensures that dump file names are unique.
/a
Generates dumps for all currently-debugged processes. If /a is used, the /u option should also be used to ensure that each file has a unique name.
/b[a]
Creates a .cab file. If this option is included, FileName is interpreted as the CAB file name, not the dump file name. A temporary dump file will be created, this file will be packaged into a CAB, and then the dump file will be deleted. If the b option is followed by a, all symbol and image files also will be packaged into the CAB.
/c "Comment"
Specifies a comment string that will be written to the dump file. If Comment contains spaces, it must be enclosed in double quotes. When the dump file is loaded, the Comment string will be displayed.
/xc Address
(User mode minidumps only) Adds a context record to the dump file. Address must specify the address of the context record.
/xr Address
(User mode minidumps only) Adds an exception record to the dump file. Address must specify the address of the exception record.
/xp Address
(User mode minidumps only) Adds a context record and an exception record to the dump file. Address must specify the address of an EXCEPTION_POINTERS structure which contains pointers to the context record and the exception record.
/xt ThreadID
(User mode minidumps only) Specifies the thread ID of a the system thread that will be used as the exception thread for this dump file.
/kpmf File
(Only when creating a kernel-mode Complete Memory Dump) Specifies a file that contains physical memory page data.
FileName
Specifies the name of the dump file. You can specify a full path and file name or just the file name. If the file name contains spaces, FileName should be enclosed in quotation marks. If no path is specified, the current directory is used.
-?
Displays help for this command. This text is different in kernel mode and in user mode.


Environment
Modes user mode, kernel mode
Targets live, crash dump
Platforms all


Comments
This command can be used in a variety of situations:

During live user-mode debugging, this command directs the target application to generate a dump file, but the target application does not terminate.
During live kernel-mode debugging, this command directs the target computer to generate a dump file, but

the target computer does not crash.
During crash dump debugging, this command creates a new crash dump file from the old one. This is useful if you have a large crash dump file and want to create a smaller one.
You can control what type of dump file will be produced:

In kernel mode, to produce a complete memory dump, use the /f option. To produce a small memory dump, use the /m option (or no options). The .dump command cannot produce a kernel memory dump.
In user mode, .dump /m[MiniOptions] is the best choice. Although "m" stands for "minidump", the dump files created by using this MiniOption can vary in size from very small to very large. By specifying the proper MiniOptions you can control exactly what information is included. For example, .dump /ma produces a dump with a great deal of information. The older command, .dump /f, produces a moderately large "standard dump" file and cannot be customized.
You cannot specify which process is dumped. All running processes will be dumped.


The /xc, /xr, /xp, and /xt options are used to store exception and context information in the dump file. This allows .ecxr (Display Exception Context Record) to be run on this dump file.

The following example will create a user-mode minidump, containing full memory and handle information:

0:000> .dump /mfh myfile.dmp



Handle information can be read by using the !handle extension command.






indbg调试命令 收藏
WinDbg是微软开发的免费源码级调试工具。Windbg可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件。由于大部分程序员不需要做Kernel模式调试, 我在这篇文章中不会介绍Kernel模式调试。Kernel模式调试对学习Windows核心极有帮助。如果你对此感兴趣,可以阅读Inside Windows 2000和Windbg所带的帮助文件。

这篇文章得主要目的是介绍WINDBG的主要功能以及相关的命令。关于这些命令的详细语法,请参阅帮助文件。对文章中提到的许多命令,WINDBG有相应的菜单选项。
如何得到帮助

在命令(Command)窗口中输入.hh 命会调出帮助文件令。

.hh keyword
会显示关于keyword的详细命令。

启动DEBUGGER

Windbg可以用于如下三种调试:

远程调试:你可以从机器A上调试在机器B上执行的程序。具体步骤如下:
? 在机器B上启动一个调试窗口(Debug Session)。你可以直接在Windbg下运行一个程序或者将Windbg附加(Attach)到一个进程。
? 在机器B的Windbg命令窗口上启动一个远程调试接口(remote):
.server npipe:pipe=PIPE_NAME
PIPE_NAME是该接口的名字。
? 在机器A上运行:
windbg –remote npipe:server=SERVER_NAME,pipe=PIPE_NAME
SERVER_NAME是机器B的名字。
Dump文件调试:如果在你的客户的机器上出现问题,你可能不能使用远程调试来解决问题。你可以要求你的用户将Windbg附加到出现

问题的进程上,然后在命令窗口中输入:
.dump /ma File Name
创建一个Dump文件。在得到Dump文件后,使用如下的命令来打开它:
windbg –z DUMP_FILE_NAME

本地进程调试:你可以在Windbg下直接运行一个程序:
Windbg “path to executable” arguments
也可以将Windbg附加到一个正在运行的程序:
Windbg –p “process id”
Windbg –pn “process name”
注意有一种非侵入(Noninvasive)模式可以用来检查一个进程的状态并不进程的执行。当然在这种模式下无法控制被调试程序的执行。这种模式也可以用于查看一个已经在Debugger控制下运行的进程。具体命令如下:
Windbg –pv –p “process id”
Windbg –pv –pn “process name”

调试多个进程和线程

如果你想控制一个进程以及它的子进程的执行,在Windbg的命令行上加上-o选项。Windbg中还有一个新的命令.childdbg 可以用来控制子进程的调试。如果你同时调试几个进程,可以使用 | 命令来显示并切换到不同的进程。
在同一个进程中可能有多个线程。~命令可以用来显示和切换线程。

调试前的必备工作
在开始调试前首先要做的工作是设置好符号(Symbols)路径。没有符号,你看到的调用堆栈基本上毫无意义。Microsoft的操作系统符号文件(PDB)是对外公开的。另外请注意在编译你自己的程序选择生成PDB文件的选项。如果设置好符号路径后,调用堆栈看起来还是不对。可以使用lm, !sym noisy, !reload 等命令来验证符号路径是否正确。

Windbg也支持源码级的调试。在开始源码调试前,你需要用.srcpath设置源代码路径。如果你是在生成所执行代码的机器上进行调试,符号文件中的源码路径会指向正确的位置,所以不需要设置源代码路径。如果所执行代码是在另一台机器上生成的,你可以将所用的源码拷贝(保持原有的目录结构)的一个可以访问的文件夹(可以是网络路径)并将源代码路径设为该文件夹的路径。注意如果是远程调试,你需要使用.lsrcpath来设置源码路径。

静态命令:
显示调用堆栈:在连接到一个调试窗口后,首先要知道的就是程序当前的执行情况k* 命令显示当前线程的堆栈。~*kb会显示所有线程的调用堆栈。如果堆栈太长,Windbg只会显示堆栈的一部分。.kframes可以用来设置缺省显示框架数。

显示局部变量:接下来要做通常是用dv显示局部变量的信息。CTRL+ALT+V可以切换到更详细的显示模式。关于dv要注意的是在优化过的代码中dv的输出极有可能是不准确的。这时后你能做的就是阅读汇编代码来发现你感兴趣的值是否存储在寄存器中或堆栈上。有时后当前的框架(Frame)上可能找不到你想知道的

数据。如果该数据是作为参数传到当前的方法中的,可以读一读上一个或几个框架的汇编代码,有可能该数据还在堆栈的某个地址上。静态变量是储存在固定地址中的,所以找出静态变量的值较为容易。.Frame(或者在调用堆栈窗口中双击)可以用来切换当前的框架。注意dv命令显示的是当前框架的内容。你也可在watch窗口中观察局部变量的值。

显示类和链表: dt可以显示数据结构。比如dt PEB 会显示操作系统进程结构。在后面跟上一个进程结构的地址会显示该结构的详细信息:dt PEB 7ffdf000。
Dl命令可以显示一些特定的链表结构。

显示当前线程的错误值:!gle会显示当前线程的上一个错误值和状态值。!error命令可以解码HRESULT。

搜索或修改内存:使用s 命令来搜索字节,字或双字,QWORD或字符串。使用e命令来修改内存。

计算表达式:?命令可以用来进行计算。关于表达式的格式请参照帮助文档。使用n命令来切换输入数字的进制。

显示当前线程,进程和模块信息:!teb显示当前线程的环境信息。最常见的用途是查看当前线程堆栈的起始地址,然后在堆栈中搜索值。!peb显示当前进程的环境信息,比如执行文件的路径等等。lm显示进程中加载的模块信息。


显示寄存器的值:r命令可以显示和修改寄存器的值。如果要在表达式中使用寄存器的值,在寄存器名前加@符号(比如@eax)。


显示最相近的符号:ln Address。如果你有一个C++对象的指针,可以用来ln来查看该对象类型。

查找符号:x命令可以用来查找全局变量的地址或过程的地址。x命令支持匹配符号。x kernel32!*显示Kernel32.dll中的所有可见变量,数据结构和过程。


查看lock:!locks显示各线程的锁资源使用情况。对调试死锁很有用。

查看handle:!handle显示句柄信息。如果一段代码导致句柄泄漏,你只需要在代码执行前后使用!handle命令并比较两次输出的区别。有一个命令!htrace对调试与句柄有关的Bug非常有用。在开始调试前输入:
!htrace –enable
然后在调试过程中使用!htrace handle_value 来显示所有与该句柄有关的调用堆栈。

显示汇编代码:u。

程序执行控制命令:
设置代码断点:bp/bu/bm 可以用来设置代码断点。你可以指定断点被跳过的次数。假设一段代码KERNEL32!SetLastError在运行很多次后会出错,你可以设置如下断点:
bp KERNEL32!SetLastError 0x100.
在出错后使用bl 来显示断点信息(注意粗体显示的值):
0 e 77e7a3b0 004f (0100) 0:*** KERNEL32!SetLastError
重新启动调试(.restart命令)并设置如下的断点:
bp Kernel32!SetLastError 0x100-0x4f
Debugger会停在出错前最后一次调用

该过程的地方。

你可以指定断点被激活时Debugger应当执行的命令串。在该命令串中使用J命令可以用来设置条件断点:
bp `mysource.cpp:143` "j (poi(MyVar)”0n20) ''; 'g' "
上面的断点只在MyVar的值大于32时被激活(g命令

条件断点的用途极为广泛。你可以指定一个断点只在特殊的情况下被激活,比如传入的参数满足一定的条件,调用者是某个特殊的过程,某个全局变量被设为特殊的值等等。

设置内存断点:ba可以用来设置内存断点。调试过程中一个常见的问题是跟踪某些数据的变化。如下的断点:
ba w4 0x40000000 "kb; g"
可以打印出所有修改0x40000000的调用堆栈。

控制程序执行:p, pa,t, ta等命令可以用来控制程序的执行。

控制异常和事件处理:Debugger的缺省设置是跳过首次异常(first chance expcetion),在二次异常(second chance exception)时中断程序的执行。sx命令显示Debugger的设置。sxe和sxd可以改变Debugger的设置。
sxe clr
可以控制Debugger在托管异常发生时中断程序的执行。常用的Debugger事件有:
av 访问异常
eh C++异常
clr 托管异常
ld 模块加载
-c 选项可以用来指定在事件发生时执行的调试命令。

相关主题