简介

让我们从我写这篇文章的原因开始。一天,一个同事让我帮他调试他遇到的问题。所以我看着他在输入代码,这时我注意到下面一行:

int test = GetLastError();

他这样做是因为他想知道错误代码,如果之前的函数失败了。他每次想知道错误代码就加上这一行。我建议他删除所有这些行并在他的监视窗口中使用@ERR伪寄存器。他不知道这是什么,在办公室里到处打听,很多人都不知道,所以我为从来没有听说过伪寄存器的人写了这篇文章。

什么是伪寄存器?

伪寄存器不是当前的硬件寄存器,而是像硬件寄存器一样显示。使用伪寄存器,您可以在调试器中看到并使用某些值(错误代码、线程信息块…)。让我们看看@ERR伪寄存器。用您最喜欢的应用程序启动调试器。在代码中放置断点,以便调试器中断执行。打开“监视”窗口(如果尚未打开)(右键单击某个空工具栏空间,然后从该列表中选择“监视”来执行此操作)。在这个监视窗口中添加@ERR。您应该在值列中看到0。现在检查一下你的代码,看看这个值。它将始终显示当前线程的GetLastError()数字。所以如果你的代码出错了,这个值就会改变。
如果你想测试这个,但是你的代码没有任何错误,我建议你放一些进去(但是不要忘记以后删除它们)。您可以插入如下内容:

FILE *fp = fopen("c:\\a_file_that_does_not_exist.txt", "r");

如果执行这一行,就会看到@ERR值变为2。转到“工具”->“错误查找”查看此错误值的含义(“如果您想知道,系统找不到指定的文件”)。像我这样懒散的流浪汉,还有像你这样聪明的小伙子/姑娘,可以把@ERR伪寄存器改成@ERR,hr。这样做会将伪寄存器的值更改为错误字符串。现在您甚至不必查找错误。我一直把“@ERR,hr”放在观察窗里。

条件表达式

伪寄存器也可用于条件表达式。要尝试此操作,请在fopen后面加上以下行:

if (fp)
{
fclose(fp);
}
在if(fp)行上设置断点。转到“编辑”->“断点”(或按Alt-F9)。选择刚才插入的断点并按“条件”按钮。在这里,您可以输入@ERR==2条件。现在启动调试器。如果fopen()由于找不到文件而失败,调试器将在此断点上中断。如果文件确实存在,调试器将不会中断,即使它遇到另一个错误(例如错误4:无法打开文件)。通过在创建后运行代码(不是步进),并在c:\中删除“AyFieleToSodoSoNothOx.Txt”文件来尝试这一点。

只是为了好奇(或者与本文完全无关):ERR做什么?它如何得到错误号?事实证明,@ERR所做的与GetLastError()所做的完全相同。这些函数有多达3行的汇编代码:

mov eax,fs:[00000018h]
mov eax,dword ptr [eax+34h]
ret

因此,@ERR在fs:[18h]指向的线程环境块中获取偏移量0x34处的DWORD。

@TIB伪寄存器

@ERR伪寄存器不是唯一存在的寄存器。另一个重要的伪寄存器是@TIB。这是当前线程的线程信息块,在多线程调试中非常有用。如果在由多个线程调用的函数中放置断点,则无论哪个线程通过断点,调试器都将每次中断执行。即使正在单步执行代码,如果另一个线程调用该函数,调试器也可以跳到断点。要解决这个问题,您需要执行以下操作。如果要执行的线程中断,请在监视窗口中添加@TIB。您将在常规显示中看到一些值,如“0x7ffa6000”或“2147115008”。转到断点菜单(Alt-F9)并选择断点。现在可以添加@TIB==0x7ffa6000条件筛选器。这样做,调试器只会中断此线程的执行。使用同一函数的所有其他线程都不会导致中断。

但这在Windows98中不起作用。对于Windows98,您需要查看Intel CPU FS寄存器,它对每个线程都是唯一的。您可以使用表达式@FS==value。

伪寄存器的完整列表

Pseudoregister Description
@ERR Last error value; the same value returned by the GetLastError() API function
@TIB Thread information block for the current thread; necessary because the debugger doesn't handle the "FS:0" format
@CLK Undocumented clock register; usable only in the Watch window
@EAX, @EBX, @ECX, @EDX, @ESI, @EDI, @EIP, @ESP, @EBP, @EFL Intel CPU registers
@CS, @DS, @ES, @SS, @FS, @GS Intel CPU segment registers
@ST0, @ST1, @ST2, @ST3, @ST4, @ST5, @ST6, @ST7 Intel CPU floating-point registers

利用伪寄存器对MSVC++进行调试的介绍的更多相关文章

  1. 从知乎首页用户操作入口学习到的CSS技巧 - 合理利用伪元素实现一些装饰样式

    最近在模仿做一个静态的PC版知乎,在模仿的过程中,从知乎工程师的方法中学到了不少知识,比如CSS方面的,以下介绍一个今天学到的伪元素的技巧. 示例 DOM结构为: <div class=&quo ...

  2. 简单的纯css重置input单选多选按钮的样式--利用伪类

    由于input单选多选的原生样式通常都不符合需求,所以在实现功能时通常都需要美化按钮 html <input type="radio" /> <input typ ...

  3. 通过win下的eclipse连接虚拟机中伪分布的hadoop进行调试

    VMware虚拟机配置Ubuntu桥接方式(Bridged)使虚拟机和宿主机能互相ping通, 通过win下的eclipse连接虚拟机中伪分布的hadoop进行调试 1.设置Bridged上网方式 V ...

  4. 风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击

    风炫安全web安全学习第三十三节课 文件包含漏洞基础以及利用伪协议进行攻击 文件包含漏洞 参考文章:https://chybeta.github.io/2017/10/08/php文件包含漏洞/ 分类 ...

  5. 利用Jemalloc进行内存泄漏的调试

    内存不符预期的不断上涨,可能的原因是内存泄漏,例如new出来的对象未进行delete就重新进行复制,使得之前分配的内存块被悬空,应用程序没办法访问到那部分内存,并且也没有办法释放:在C++中,STL容 ...

  6. Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法:

    Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法: ------------------------------------------------------------ ...

  7. 利用Python进行数据分析——重要的Python库介绍

    利用Python进行数据分析--重要的Python库介绍 一.NumPy 用于数组执行元素级计算及直接对数组执行数学运算 线性代数运算.傅里叶运算.随机数的生成 用于C/C++等代码的集成 二.pan ...

  8. 利用伪元素和css3实现鼠标移入下划线向两边展开效果

    一.思路: 将伪元素:before和:after定位到元素底部中间,设置宽度从0变成100%达到目的. 二.实现: 1.首先定义一个块状元素(行内元素没有宽高)并修改样式为一个背景色为浅灰色的矩形,设 ...

  9. mac下利用Breakpad的dump文件进行调试

    一.前情回顾 最近把公司的一个视频处理程序更新了一个版本,准备提交测试的发现了崩溃的情况.这个程序采用Qt和ffmpeg技术栈开发,主要用于对视频进行渲染拼接处理,在Windows和mac两个平台同时 ...

随机推荐

  1. (一)将mockjs集成到VUE中后,怎样根据接口入参返回mock结果

    1)安装mockjs,这一步跳过 2)在项目中建立mock模块,笔者的目录结构如下 mock模块与接口模块一一对应,有一个接口,就有一个mock 3)编写登陆模块mock接口,代码如下: import ...

  2. python 搭建 websocket server 发送 sensor 数据

    搞了几天,顺便把代码贴这里,需要的 python 包: gevent,gevent-websocket,bottle,wiringpi-python 简单说明: - gevent 提供了支持 conc ...

  3. 示例:WPF仿制OSK做的系统键盘和数字键盘

    原文:示例:WPF仿制OSK做的系统键盘和数字键盘 一.目的:在应用osk.exe系统键盘时遇到很多不方便,比如有些系统调用不出来等问题,由此开发了一个系统键盘仿制osk 二.实现功能 1.目前实现大 ...

  4. C#读写设置修改调整UVC摄像头画面-对比度

    有时,我们需要在C#代码中对摄像头的对比度进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄 ...

  5. Golang逃逸分析

    Golang逃逸分析 介绍逃逸分析的概念,go怎么开启逃逸分析的log. 以下资料来自互联网,有错误之处,请一定告之. sheepbao 2017.06.10 什么是逃逸分析 wiki上的定义 In ...

  6. Android Scroller简单用法实例

    Android里Scroller类是为了实现View平滑滚动的一个Helper 类.通常在自定义的View时使用,在View中定义一个私有成员mScroller = new Scroller(cont ...

  7. Shell 冒泡排序

    举例 #!/bin/bash echo "please input a number list:" read -a arrs for((i=0;i<${#arrs[@]};i ...

  8. springmvc核心流程

    用户请求DispathcerServlet(前端控制器). (前端控制器)DispatcherServlet接受到请求,将根据请求信息交给处理器映射器(HandlerMapping). 处理器映射器( ...

  9. Django 之 Form 组件

    常用功能 From 组件主要有以下几大功能: 生成 HTML 标签 验证用户数据(显示错误信息) HTML Form 提交保留上次提交数据 初始化页面显示内容 小试牛刀 下面我们通过 Form 组件来 ...

  10. HDFS 配额教程

    本文原始地址:https://sitoi.cn/posts/12544.html 名称配额(Name Quota) 名称配额是在对应的目录下所有文件和目录名称的数量上的限制. 当超过这个配额的时候,文 ...