MSVC的调试技巧

MSVC 的调试技巧 : Pseudoregisters
- 翻译自 CodeProject.com
让我们从为什么写这篇文章开始 . 一天 , 一个学生让我帮助他解决一个调试问题 . 为此我看着他单步进入代码 , 当我看到如下代码 :
int test = GetLastError();
他这样做事为了知道之前函数失败的错误代码 . 每次他需要知道错误代码的时候都添加上面的代码行 . 我建议他删除所有的代码行代之以调试 ”Watch” 窗口当中添加 ”@ERR”. 他不知道这是什么 , 在场的其他人也不知道这是什么技术 . 所以我写下这篇文章给那些从未听说过 ”pseudoregisters” 技术的人 .
什么是 ”pseudoregister” 技术 ?
“pseudoregister” 并不是一个真正的硬件寄存器 . 利用 pseudoregister 可以查看并且使用调试器当中的特定值 ( 错误代码 , 线程信息块 , …).
让我们看看 @ERR. 启动一个调试应用程序 . 在你的代码放置断点便于调试器中断执行 . 打开 Watch 窗口 , 添加 @ERR 到窗口 . 你可以在值列看到值为零 . 现在可以调试你的代码并且查看数值 . @ERR 总是显示当前线程的 GetLastError() 数值 . 当执行发生错误的时候 , 数值就会改变了 .
要测试 , 写下如下导致错误的代码 :
FILE *fp = fopen( "c:\\a_file_that_does_not_exist.txt" , "r" );
步入上述代码行的时候 , @ERR 数值修改成为 2. 利用 Tools->Error Lookup 可以查看对应的错误代码解释为 ("The system cannot find the file specified"). 如果添加 ”,hr”, 错误信息就会显示出来 , 不用 ”Error Lookup” 工具了 ( 译者 : 一般 ”err, hr” 也是一样的 )
条件表达式
Pseudoregisters 也可以被使用在条件表达式当中 , 添加如下代码行到 fopen:
if (fp)
{
      fclose(fp);
}
"if (fp)" 添加断点 . 利用 Edit->Breakpoints (Alt-F9) 添加条件 @ERR== 2” . 启动调试以后 , fopen() 文件不存在的时候进入断点 . 如果文件存在断点不会触发 , 即使在触发其他错误的时候也是如此 ( 例如 4: 无法打开指定文件 ).
@TIB pseudoregister
@ERR 不是唯一的调试寄存器 . 另一个重要的寄存器是 @TIB. 这是当前线程的信息并且对于多线程调试非常有用 . 如果你在多线程调用的函数当中添加断点 , 调试器在不管什么线程调用的时候总是触发断点 . 即使你步出代码也会进入另一个线程调用 ( 断点 ). 要解决这个问题 , 你需要进行以下错误 . 如果要触发指定线程的断点 , 添加 @TIB 寄存器 . 你会看到诸如 "0x7ffa6000" 或者 "2147115008" 的寄存器值 . 编辑断点条件 , 设置条件 @TIB== 0x7ffa6000 . 这样 , 调试器仅仅会在指定线程触发 . 其他调用同一个函数的线程不会触发 .
不过这对于 Win98 不适用 . 对于 Windows 98, 需要利用 Intel CPU 的寄存器 @FS==value
完整的寄存器列表 :
Pseudoregister
Description
@ERR
最后错误值 ; GetLastError () API 函数一致
@TIB
当前线程信息 ; 在调试器无法处理 ”FS:0” 格式的时候是必要的
@CLK
未列入文档的寄存器 ; 只是在 Watch 窗口适用
@EAX, @EBX, @ECX, @EDX, @ESI, @EDI, @EIP, @ESP, @EBP, @EFL
Intel CPU 寄存器
@CS, @DS, @ES, @SS, @FS, @GS
Intel CPU 段寄存器
@ST0, @ST1, @ST2, @ST3, @ST4, @ST5, @ST6, @ST7
 
本文来自:[url]http://blog.csdn.net/rick1126/archive/2002/10/08/2704.aspx[/url]  
Intel CPU 浮点rick1126的专栏寄存器
 

你可能感兴趣的:(职场,休闲,调试技巧)