2011-9-27

  烛秋

 

  昨天、今天调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,这样在命令行执行遇到崩溃的时候就会停下来。

 

  (本文最后的学习资料相当好)

 

 

测试程序:

///////////////////////////////////////////////////////////////////////////////////

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说明分配空间时不对齐,保证一旦越界立即发现,不会因为内存对齐而隐藏起来。

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

 

posted on 2011-09-27 20:20  烛秋  阅读(15376)  评论(2编辑  收藏  举报