zoukankan      html  css  js  c++  java
  • 使用伪寄存器调试MSVC++程序的介绍An introduction to debugging in MSVC++ using Pseudoregisters

    对于伪寄存器,百度到的结果很少,翻译此篇供各位同学参考吧。

    原文链接:

    http://www.codeproject.com/KB/debug/pseudoregister.aspx

     

    介绍:

    下面介绍一下我写这篇文章的原因。今天我的一个同事让我帮他调试一个他遇到的问题。我看他单步他的程序的时候,发现了下面的代码:

    int test = GetLastError();

    他这样做因为他希望如果之前的函数失败了能够知道错误码。我建议他移除这些行并且在Watch Window中使用伪寄存器@ERR。他不知道这是什么,并且问周围的同事,周围的很多人也不知道。所以我决定为那些从来没有听说过伪寄存器的人们写这篇文章。

    到底什么是伪寄存器呢?

    伪寄存器不是真正的硬件寄存器,但是他显示起来就像硬件寄存器一样。使用伪寄存器你可以在调试器中看到并使用一些值(错误码,线程模块信息)。

    让我们来开看一看伪寄存器@ERR。调试任意一个你写好的应用程序。在你的代码中添加一个断点。打开Watch Window(如果没有的话),右击工具条的空白处,选择Watch。在Watch Window中添加@ERR。这是你会在Value那一列看到0。这时再单步你的程序,来观察他的值。它总是会显示当前线程的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" 系统找不到指定的文件)。还有一些像我一样的懒人,或者聪明的家伙会将@ERR 伪寄存器改成@ERR,hr,这样做将会把伪寄存器的值变为错误字符串。这样你就不用去查错误码了。我总是将@ERR,hr保留在watch window

    条件表达式

    伪寄存器可以用来作为条件表达式。要试一下的话,在fopen之后添加下面几行代码:

    if (fp)

    {

        fclose(fp);

    }

    if (fp) 这一行加一个断点。Go to Edit->Breakpoints(或者按F9)选择你刚添加的断点。并且单击"Condition"按钮。在这输入条件 @ERR==2。这是再启动调试器。这是调试器只会在fopen()因为找不到文件失败的情况下被断下。如果他遇到了其他的错误(比如4could not open the file,不能打开文件)。尝试在创建文件之后运行代码,然后删除c:/下的文件"a_file_that_does_not_exist.txt"

    仅仅是因为好奇(否则完全与这篇文章无关);@ERR做了些什么?它是怎样获得错误码的。事实上,@ERR做了和GetLastError() 相同的事情。这些函数只有三行汇编代码:

    mov eax,fs:[00000018h]

    mov eax,dword ptr [eax+34h]

    ret

    所以 @ERR 获取了当前线程环境中指向fs:[18h]的偏移0x34DWORD 

    伪寄存器@TIB

    @ERR伪寄存器不是唯一存在的伪寄存器。另一个重要的伪寄存器是@TIB.这是当前的线程信息块。并且在多线程程序的调试中非常有用。如果你在一个会被多个线程调用的函数中添加一个断点。调试器会在每次函数被调用的时候都断下而不管调用的是哪个线程。如果你想单步进入你的代码,调试器会跳到断点,当别的线程调用这个函数的时候。为了解决这个问题,你需要这样来做。要在你期望的线程进入断点,你需要做下面的一些事情。添加@TIBwatch window。你会看到一些值"0x7ffa6000" or "2147115008"。到断点菜单(Alt-F9),选择你设置的断点。添加@TIB==0x7ffa6000条件过滤。这样,你的调试器就只会在执行到这个线程的时候才会进入断点。其它的调用这个线程函数不会触发断点。

    这对Windows 98不行。对Windows 98,你需要查看CPU FS寄存器。它对每个线程都是不同的。你可以使用条件:@FS==value

     

  • 相关阅读:
    Node.js NPM 包(Package)
    Node.js NPM 作用
    Node.js NPM 介绍
    Node.js NPM 教程
    Node.js NPM 教程
    Node.js 发送Email
    Node.js 上传文件
    Node.js 事件
    Node.js NPM
    Node.js 文件系统模块
  • 原文地址:https://www.cnblogs.com/oyjj/p/2132891.html
Copyright © 2011-2022 走看看