简介

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

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. 查看电脑已保存的wifi及密码

    1. 查看以保存的wifi名称  打开cmd(win+r) #查看已保存WiFi名称 netsh wlan show profiles 2. 查看已保存的wifi的密码 netsh wlan show ...

  2. 『2019 SummerCamp 总结』

    做题 对于习题方面,我们感觉一个暑假还是留下了不少的题要写,大部分应该是讲师讲课的例题,还有少部分考试题.考试题没有订正完是因为还有算法不会,或是因为题太毒瘤了不会.同时,也发现自己还是有很多应该学的 ...

  3. 【华为云实战开发】10.经典的C++项目怎么在云端开发?【华为云技术分享】

    1 概述 1.1 文章目的 本文主要想为研发C++项目的企业或个人提供上云指导,通过本文中的示例项目 “音频解析器”,为开发者提供包括项目管理,代码托管,代码检查,编译构建,测试管理的操作指导,覆盖软 ...

  4. DotnetSpider爬虫简单示例 net core

    文章地址 https://blog.csdn.net/sD7O95O/article/details/78097556 安装爬虫框架  NUGET 安装DotnetSpider 创建HTTP协议数据包 ...

  5. DataTable求列的最大值、最小值、平均值和样本数

    与sql聚合函数相似,会屏蔽null table.Compute("max(ColumnName)", "true"); table.Compute(" ...

  6. Python进阶----pymysql的安装与使用,mysql数据库的备份和恢复,mysql的事务和锁

    Python进阶----pymysql的安装与使用,mysql数据库的备份和恢复,mysql的事务和锁 一丶安装 pip install PyMySQL 二丶pymysql连接数据库 ### 语法: ...

  7. 全程实操cdh5.14.4中集成安装kylin2.4.1与使用测试

    在cdh5.14.4安装完成并排错完成的情况下,进行如下kylin安装操作: 1.实验环境 三台CentOS 7主机,IP地址 192.168.43.129 cm1 192.168.43.130 cm ...

  8. 30、filter数组去重

    eg: let arr=[1,0,0,9,7,7,5,2] let data=arr.filter((item,index,self)=> self.indexOf(item)===index ...

  9. java接口中的成员方法和成员变量

    接口的含义理解:接口可以理解成统一的"协议",而接口中的属性也属于协议中的内容;但是接口的属性都是公共的,静态的,最终的 接口的成员特点:A:成员变量 只能是常量.默认修饰符 pu ...

  10. Ubuntu 18.04 + Gtx 1660 安装Nvidia 显卡驱动

    1.UEFI禁用secure boot(我的系统是win10主系统,引导ubuntu,安装驱动前电脑存在win10 uefi引导问题) Make sure the "OS Type" ...