技术开发 频道

10个Visual Studio原生开发的调试技巧

  提示7:在系统DLL调用处暂停

  有时在DLL的某个函数被调用时暂停是很有用,特别是系统DLL(比如kernel32.dll、user32.dll)。实现这种暂停需要使用原生debugger提供的上下文运算符。你可以设定断点位置、变量名或者表达式:

  • {[函数],[源代码],[模块]}断点位置

  • {[函数],[源代码],[模块]}变量名

  • {[函数],[源代码],[模块]}表达式

  大括号内可以是函数名、源代码及模块的任意组合,但是逗号不能省略。

  举个例子如果我们需要在CreateThread函数调用时暂停。这个函数是从kernel32.dll导出的,因此上下文运算符应该是这样子的:{,,kernel32.dll}CreateThread。然而,这样并不行,因为该运算符需要CreateThread修饰之后的名字。可以使用 DBH.exe来获得一个特定函数的修饰名(编译器编译生成)。

  下面是如何获得CreateThread的修饰名的方法:

C:\Program Files (x86)\Debugging Tools for Windows (x86)>dbh.exe -s:srv*C:\Symbo
ls
*http://msdl.microsoft.com/Download/Symbols -d C:\Windows\SysWOW64\kernel32.dl
l enum *CreateThread*
Symbol Search Path: srv
*C:\Symbols*http://msdl.microsoft.com/Download/Symbols

index            address     name
    
1            10b4f65 :   _BaseCreateThreadPoolThread@12
    
2            102e6b7 :   _CreateThreadpoolWork@12
    
3            103234c :   _CreateThreadpoolStub@4
    
4            1011ea8 :   _CreateThreadStub@24
    
5            1019d40 :   _NtWow64CsrBasepCreateThread@12
    
6            1019464 :   ??_C@_0BC@PKLIFPAJ@SHCreateThreadRef?$AA@
    
7            107309c :   ??_C@_0BD@CIEDBPNA@TF_CreateThreadMgr?$AA@
    
8            102ce87 :   _CreateThreadpoolCleanupGroupStub@0
    
9            1038fe3 :   _CreateThreadpoolIoStub@16
     a            102e6f0 :   _CreateThreadpoolTimer@
12
     b            102e759 :   _CreateThreadpoolWaitStub@
12
     c            102ce8e :   _CreateThreadpoolCleanupGroup@
0
     d            102e6e3 :   _CreateThreadpoolTimerStub@
12
     e            1038ff0 :   _CreateThreadpoolIo@
16
     f            102e766 :   _CreateThreadpoolWait@
12
    
10            102e6aa :   _CreateThreadpoolWorkStub@12
    
11            1032359 :   _CreateThreadpool@4

  看起来真实的名字是_CreateThreadStub @24。因此我们可以创建断点,{,,kernel32.dll}_CreateThreadStub @24。

在系统DLL调用处暂停

  运行程序,当遇到暂停时,直接忽略关于在断点位置无相关源代码的消息提示。

在系统DLL调用处暂停

  使用调用堆栈窗口来查看调用这个函数的代码。

在系统DLL调用处暂停

  提示8:载入符号

  当你调试程序的时候,调用堆栈窗口有可能不会显示全部的调用堆栈,其中忽略系统DLL(例如kernel32.dll, user32.dll)的信息。

在系统DLL调用处暂停

  通过加载这些DLL的符号信息,可以获得全部调用堆栈信息,并且在调用堆栈窗口,使用上下文菜单(右键菜单),直接设置这种效果。你可以从预定义的符号路径或者微软的符号服务器(针对系统DLL)下载这些符号。在这些符号下载并导入到debugger中之后,调用堆栈更新如下:

在系统DLL调用处暂停

  这些符号也可以从Module窗口导入。

在系统DLL调用处暂停

  一旦载入之后,这些符号会保存在缓存中,并且可以在Tools>Options>Debugging>Symbols中配置。

在系统DLL调用处暂停

0
相关文章