分享Visual Studio原生开发的10个调试技巧(2)(2)

  当你使用Watch或者Quick Watch窗口查看变量时,显示这些数值是用默认的预定义可视化格式。当变量是数字时,显示形式按照他们的类型(int、float、double)来的,并且使用十进制显示。然而,你可以设置调试器在显示数字的使用使用不同的类型,或者使用不同的进制。

  改变变量显示类型可以在变量前添加以下前缀:

by —— unsigned char(unsigned byte)

wo —— unsigned short(unsigned word)

dw —— unsigned long(unsigned double word)

  改变变量显示的进制可以在变量前添加以下前缀:

d或i —— 有符号十进制数

u     —— 无符号十进制数

o     —— 无符号八进制数

x     —— 小写十六进制数

X     —— 大写十六进制数

分享Visual Studio原生开发的10个调试技巧(2)

技巧16:格式化内存数据

  除了数字,debugger还可以在Watch窗口中显示格式化的内存数据,最长为64字节。你可以在表达式(变量或者内存地址)后面添加下面的后缀来格式化数据:

mb或m —— 十六进制显示的16字节数据,后面跟着16个ASCII字符

mw —— 8字(WORD,通常1 WORD = 2 BYTE)数据

md —— 4个双字(DWORD,通常1 DWORD = 4 BYTE)数据

mq —— 2个四字(Quad WORD)数据

ma —— 64个ASCII字符

mu —— 2字节UNICODE字符

分享Visual Studio原生开发的10个调试技巧(2)

技巧17:在系统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* -d C:\Windows\SysWOW64\kernel32.dl l enum *CreateThread* Symbol Search Path: srv*C:\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。

分享Visual Studio原生开发的10个调试技巧(2)

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

分享Visual Studio原生开发的10个调试技巧(2)

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

分享Visual Studio原生开发的10个调试技巧(2)

技巧18:载入符号

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

分享Visual Studio原生开发的10个调试技巧(2)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjwffx.html