昨天、今天调dump,对windbg相当的不熟悉,但也慢慢的知道了一些常用的命令,几周前听说到有gflags这样个工具,今天正好测试下。
gflags.exe是<Debugging Tools for Windows>中的一个小工具。
安装下载链接:http://msdn.microsoft.com/en-us/windows/hardware/gg463016
安装好之后,把gflags所在文件夹(这里边还有很多好东西)设置到环境变量的path中,方便命令行使用。(我的电脑-->右键-->属性-->高级-->环境变量-->系统变量-->path)
在命令行cmd里输入:cdb -iae 。
设置cdb为默认JIT(just in time) debugger,这样在命令行执行遇到崩溃的时候就会停下来。
(本文最后的学习资料相当好)
1
2
3
4
5
6
7
8
9
10
|
测试程序:
///////////////////////////////////////////////////////////////////////////////////
int
main()
{
char
*p =
new
char
[10];
for
(
int
i = 0; i != 11; ++i)
p[i] = i;
return
0;
}
///////////////////////////////////////////////////////////////////////////////////
|
这是一个非常简单的越界程序,当i = 10时,访问越界了。但是如果不采用测试工具,这里是不会发生崩溃的。一般情况下,程序获取的空间是16字节对齐的,所以p[10]访问到的是对齐之后增加的空间,不会导致越界崩溃。但这是隐患,为了使隐患尽早被发现,使用工具是很好的选择。
gflags用来跟踪这个程序的执行,可以设置每一次new分配的堆空间都单独的占有一块空间,并且这个空间相邻的位置被设置为不可访问的,一旦访问越界立即触发访问无效错误,尽早的触发崩溃。
测试过程如下:
1、用vc编译出release版本的可执行文件:test.exe。(注意:不是debug版本)
2、用gflag注册需要监控的可执行文件test.exe。
在cmd下,输入命令如下:gflags /p /enable test.exe /full /unaligned。
回车,显示如下信息:
*************************************************************************************
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
test.exe: page heap enabled。
*************************************************************************************
这个时候,已经把要监控的test.exe注册上了。
/p /enable 是必备的。
/full 说明分配的空间是独占的,并且相邻的是不可访问的空间。
/unaligned 说明分配空间时不对齐,保证一旦越界立即发现,不会因为内存对齐而隐藏起来。
上面实际上在注册表位置:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\test.exe写入了PageHeapFlags=0x23
3、接着双击执行test.exe,这个时候,会中断下来:
*************************************************************************************
(17f8.5d0): Access violation - code c0000005 (!!! second chance !!!)
eax=0161eff6 ebx=7c80ac61 ecx=0000000a edx=015c5000 esi=00000002 edi=00000a28
eip=00401010 esp=0012ff74 ebp=0012ffc0 iopl=0 nv up ei ng nz ac pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000297
WindbgTest!main+0x10:
00401010 880c01 mov byte ptr [ecx+eax],cl ds:0023:0161f000=??
*************************************************************************************
如果把exe放到windbg里执行,用命令:!address,可以发现eax是可以读写的,
eax+ecx是不可访问的:
*************************************************************************************
0:000> !address eax
015c0000 : 0161e000 - 00001000
Type 00020000 MEM_PRIVATE
Protect 00000004 PAGE_READWRITE
State 00001000 MEM_COMMIT
Usage RegionUsagePageHeap
Handle 015c1000
0:000> !address eax+ecx
015c0000 : 0161f000 - 000a1000
Type 00020000 MEM_PRIVATE
Protect 00000001 PAGE_NOACCESS
State 00001000 MEM_COMMIT
Usage RegionUsagePageHeap
Handle 015c1000
*************************************************************************************
4、取消跟踪:
通过/p命令可以看到当前跟踪的程序有哪些:
*************************************************************************************
C:\Documents and Settings\cs_wuyg>gflags /p
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
player.exe: page heap enabled with flags (full traces )
program: page heap enabled with flags (full unaligned traces )
test.exe: page heap enabled with flags (full unaligned traces )
windbgtest.exe: page heap enabled with flags (full unaligned traces )
*************************************************************************************
通过/p /disble取消跟踪:情况如下:
*************************************************************************************
C:\Documents and Settings\cs_wuyg>gflags /p /disable player.exe
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
player.exe: page heap disabled
C:\Documents and Settings\cs_wuyg>gflags /p
path: SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
program: page heap enabled with flags (full unaligned traces )
test.exe: page heap enabled with flags (full unaligned traces )
windbgtest.exe: page heap enabled with flags (full unaligned traces )
*************************************************************************************
发现program是无法取消的,很奇怪。另外,发现注册表里相应的项目在disable之后,仍然存在,只不过一些键值被删除掉了。
同事跟我说,不使用gflags的时候,最好把注册表里的项目删除,gflags对机器性能的影响很大。
注册表的位置是:HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/WindowsNT/Image File Execution Options
5、注意事项
一、gflags要跟踪的程序,是把这个程序的名称记录到了注册表中,在设置的时候不需要可执行文件的路径名,只需要文件名称。
二、可以使用命令行,也可以使用GUI界面。GUI界面中的前两个TAB页面是对所有的可执行程序都有效的。第三个才是设置想要跟踪的程序。
三、还有其它更强大的工具。
6、总结
通过这个工具的简单使用,就可以很快发现代码中有访问越界。
在大工程下,是否也非常有用,现在还没实践过。
使用gflags,并且在VS下调试,有源代码更方便。
7、附今天用上的几个windbg命令:
1\ !analyze -v
2\ kv kf kb
3\ ~*k
4\ .ecxr
5\ lmvm xxx.exe
分析dump的时候,看调用堆栈是从下往上看的。
调用堆栈前部分的数值一部分是参数,一部分是无用的信息。
设置好source file path之后,.ecxr命令可以看到当前的寄存器信息,还可以看到源代码。
发现很多的崩溃是由于空指针、野指针导致的。而空指针、野指针是由于多线程导致卸载、装载重叠导致的。
学习资料:
http://www.cppblog.com/sandy/archive/2007/03/13/19723.html
http://blog.csdn.net/ayw_hehe/article/details/6796333
http://www.cppblog.com/sandy/archive/2008/09/27/62877.html
http://www.cnblogs.com/awpatp/archive/2011/01/01/1923913.html
http://blog.sina.com.cn/s/blog_484f16880100jrwj.html
----------------------------------------------------------------------------------------
附:http://technet.microsoft.com/zh-cn/cc736347
gflags[/r [Flag [Flag...]] | /k [Flag [Flag...]] | /i ImageFile [Flag [Flag...]] | /i ImageFile /tracedb SizeInMB | /?]
gflags /p [/disable ImageFile] [/?]
gflags /p/enable ImageFile [/full [/backwards] | [/random Probability] | [/size SizeStartSizeEnd] | [/address AddressStart AddressEnd] | [/dlls DLL [DLL...]] [/debug | /kdebug] [/unaligned] [/decommit] [/notraces] [/fault Rate [TimeOut]] [/leaks] [/protect] [/no_sync] [/no_lock_checks]
Format | Description |
---|---|
{+ | -}FlagAbbr |
Sets (+) or clears (-) the flag represented by the flag abbreviation. Without a plus (+) or minus (-) symbol, the command has no effect. |
[+ | -]FlagHex |
Adds (+) or subtracts (-) the hexadecimal value of a flag. A flag is set when its value is included in the sum. Add (+) is the default. Enter a hexadecimal value (without 0x) that represents a single flag or enter the sum of hexadecimal values for multiple flags. |
The following table lists the flags that Gflags changes, the hexadecimal value and abbreviation for each flag, and the destination (R for registry, K for kernel, I for image file) in which the flag is valid.
For a detailed description of each flag, see the Gflags Flag Reference.
Caution
Important
Description | Symbolic name | Hexadecimal Value | Abbreviation | Destination |
---|---|---|---|---|
Gflags Flag Reference |
FLG_DISABLE_DBGPRINT |
0x08000000 |
ddp |
R,K |
Gflags Flag Reference |
FLG_KERNEL_STACK_TRACE_DB |
0x2000 |
kst |
R |
Gflags Flag Reference |
FLG_USER_STACK_TRACE_DB |
0x1000 |
ust |
R,K,I |
Gflags Flag Reference |
FLG_DEBUG_INITIAL_COMMAND |
0x4 |
dic |
R,K |
Gflags Flag Reference |
FLG_DEBUG_INITIAL_COMMAND_EX |
0x04000000 |
dwl |
R, K |
Gflags Flag Reference |
FLG_HEAP_DISABLE_COALESCING |
0x00200000 |
dhc |
R,K,I |
Gflags Flag Reference |
FLG_DISABLE_PAGE_KERNEL_STACKS |
0x80000 |
dps |
R,K |
Gflags Flag Reference |
FLG_DISABLE_PROTDLLS |
0x80000000 |
dpd |
R,K,I |
Gflags Flag Reference |
FLG_DISABLE_STACK_EXTENSION |
0x10000 |
dse |
I |
Gflags Flag Reference |
FLG_CRITSEC_EVENT_CREATION |
0x10000000 |
cse |
R,K,I |
Gflags Flag Reference |
FLG_APPLICATION_VERIFIER |
0x100 |
vrf |
R,K,I |
Gflags Flag Reference |
FLG_ENABLE_HANDLE_EXCEPTIONS |
0x40000000 |
bhd |
R,K |
Gflags Flag Reference |
FLG_ENABLE_CLOSE_EXCEPTIONS |
0x00400000 |
ece |
R,K |
Gflags Flag Reference |
FLG_ENABLE_CSRDEBUG |
0x20000 |
d32 |
R,K |
Gflags Flag Reference |
FLG_ENABLE_EXCEPTION_LOGGING |
0x00800000 |
eel |
R,K |
Gflags Flag Reference |
FLG_HEAP_ENABLE_FREE_CHECK |
0x20 |
hfc |
R,K,I |
Gflags Flag Reference |
FLG_HEAP_VALIDATE_PARAMETERS |
0x40 |
hpc |
R,K,I |
Gflags Flag Reference |
FLG_HEAP_ENABLE_TAGGING |
0x800 |
htg |
R,K,I |
Gflags Flag Reference |
FLG_HEAP_ENABLE_TAG_BY_DLL |
0x8000 |
htd |
R,K,I |
Gflags Flag Reference |
FLG_HEAP_ENABLE_TAIL_CHECK |
0x10 |
htc |
R,K,I |
Gflags Flag Reference |
FLG_HEAP_VALIDATE_ALL |
0x80 |
hvc |
R,K,I |
Gflags Flag Reference |
FLG_ENABLE_KDEBUG_SYMBOL_LOAD |
0x40000 |
ksl |
R,K |
Gflags Flag Reference |
FLG_ENABLE_HANDLE_TYPE_TAGGING |
0x01000000 |
eot |
R,K |
Gflags Flag Reference |
FLG_HEAP_PAGE_ALLOCS |
0x02000000 |
hpa |
R,K,I |
Gflags Flag Reference (Windows 2000 and Windows XP only) |
FLG_POOL_ENABLE_TAGGING |
0x400 |
ptg |
R |
Gflags Flag Reference |
FLG_ENABLE_SYSTEM_CRIT_BREAKS |
0x100000 |
scb |
R, K, I |
Gflags Flag Reference |
FLG_LDR_TOP_DOWN |
0x20000000 |
ltd |
R, K, I |
Gflags Flag Reference |
FLG_MAINTAIN_OBJECT_TYPELIST |
0x4000 |
otl |
R,K |
Gflags Flag Reference |
FLG_SHOW_LDR_SNAPS |
0x2 |
sls |
R,K,I |
Gflags Flag Reference |
FLG_STOP_ON_EXCEPTION |
0x1 |
soe |
R,K,I |
Gflags Flag Reference |
FLG_STOP_ON_HUNG_GUI |
0x8 |
shg |
K |