青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

鍵盤的詠嘆調

常用鏈接

統計

最新評論

[zz]An introduction to debugging in MSVC++ using Pseudoregisters

Introduction

Let's start with the reason why I wrote this article. One day, a colleague asked me to help him debug a problem he had. So I was watching him stepping in his code, when I noticed the following line:

Collapse
int test = GetLastError();

He did this, because he wanted to know the error code, if the previous function failed. He was adding this line every time he wanted to know the error code. I advised him to remove all those lines and use the @ERR pseudoregister in his watch window. He didn't know what it was and asking around in the office, a lot of other people didn't. So I came up with this article for people who have never heard of pseudoregisters.

What is a pseudoregister anyway?

A pseudoregister is not an actual hardware register, but is displayed as though it were a hardware register. With a pseudoregister, you can see and use certain values (error codes, thread information block...) in the debugger.

Let's have a look at the @ERR pseudoregister. Fire up your debugger with your favourite home-written application. Put a breakpoint in your code so that the debugger will break execution. Open the watch window if it isn't already (do this by right clicking on some empty toolbar space, and select "Watch" from this list). Add @ERR in this watch window. You should see 0 in the Value column. Now step through your code, and watch this value. It will always show the GetLastError() number for the current thread. So if something goes wrong in your code, this value will change.

If you want to test this, but your code doesn't have any errors, I advise to put some in (but don't forget to remove them afterwards). You can insert something like this:

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

If you step over this line, you'll see that the @ERR value changed to 2. Go to Tools->Error Lookup to see what this error value means ("The system cannot find the file specified" if you were wondering). Lazy bums like me, and smart lads / lasses like you can change the @ERR pseudoregister to @ERR,hr . Doing this will change the value of the pseudoregister to the error string. Now you even don't have to lookup the error. I leave the @ERR,hr in the watch window all the time.

Conditional Expressions

Pseudoregisters can also be used in conditional expressions. To try this out, put following lines after the fopen:

Collapse
if (fp)
{
fclose(fp);
}

Put a breakpoint on the if (fp) line. Go to Edit->Breakpoints (or press Alt-F9). Select the breakpoint you just inserted and press the "Condition" button. Here, you can enter the @ERR==2 condition. Now start the debugger. The debugger will break on this breakpoint if fopen() failed because it couldn't find the file. If the file does exist, the debugger won't break, even if it encountered another error (say error 4: could not open the file). Try this out by running the code (not stepping) after creating, and deleting the "a_file_that_does_not_exist.txt" file on c:\.

Just for the very curious (and otherwise totally irrelevant to this article) : what does @ERR do? How does it get the error number? As it turns out, @ERR does exactly the same thing as GetLastError() does. These functions have a whopping 3 lines of assembly code:

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

So @ERR grabs the DWORD at offset 0x34 in the thread environment block pointed to by fs:[18h].

The @TIB pseudoregister

The @ERR pseudoregister is not the only one that exists. Another important pseudoregister is @TIB. This is the thread information block for the current thread and is extremely helpful in multi-threaded debugging. If you place a breakpoint in a function that is called by multiple threads, the debugger will break execution every time no matter which thread passes the breakpoint. Even if you're stepping through your code, the debugger can jump to the breakpoint if another thread called the function. To solve this, you'll need to do the following. If execution breaks in the thread you want, add @TIB in the watch window. You will see some value like "0x7ffa6000" or "2147115008" in regular display. Go to the breakpoint menu (Alt-F9) and select the breakpoint. You can now add the @TIB==0x7ffa6000 condition filter. Doing this, the debugger will only break execution for this thread. All other threads using the same function will not result in a break.

This doesn't work in Windows 98 though. For Windows 98, you'll need to look at the Intel CPU FS register, which is unique for each thread. You can use the expression @FS==value

Complete list of pseudoregisters

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

posted on 2009-11-18 09:49 鍵盤的詠嘆調 閱讀(275) 評論(0)  編輯 收藏 引用 所屬分類: C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久这里有精品视频| 欧美大色视频| 亚洲一线二线三线久久久| 欧美日韩亚洲一区在线观看| 在线视频你懂得一区二区三区| 亚洲人成亚洲人成在线观看| 久久人人精品| 亚洲欧洲在线播放| 亚洲国产欧美不卡在线观看| 欧美成人一区二区三区| 亚洲人成免费| av成人老司机| 国产欧美欧洲在线观看| 久久免费国产精品1| 久久精品在线| 亚洲美女在线视频| 一区二区高清在线| 国产一区二区久久久| 模特精品裸拍一区| 欧美伦理一区二区| 欧美一区三区三区高中清蜜桃 | a4yy欧美一区二区三区| 99精品国产99久久久久久福利| 国产精品国产精品国产专区不蜜| 午夜精品理论片| 久久久精品网| 亚洲免费视频网站| 亚洲综合精品自拍| 午夜一区二区三区不卡视频| 亚洲国产精品女人久久久| 日韩视频亚洲视频| 韩日视频一区| 一区二区国产精品| 亚洲高清不卡一区| 在线一区亚洲| 亚洲三级视频| 欧美在线观看日本一区| 一区二区三区四区国产| 久久大逼视频| 午夜精品美女自拍福到在线| 老司机精品久久| 欧美专区中文字幕| 欧美日韩午夜| 亚洲大胆人体视频| 老司机精品视频一区二区三区| 国产精品99久久久久久久vr| 久久综合色天天久久综合图片| 亚洲一区精彩视频| 欧美激情第8页| 美国三级日本三级久久99| 国产精品久久久久久妇女6080| 欧美电影打屁股sp| 好吊妞**欧美| 校园春色国产精品| 午夜久久tv| 国产精品swag| 日韩一区二区精品| 99re热精品| 欧美成人午夜激情| 欧美国产视频日韩| 激情成人中文字幕| 欧美一区二区三区男人的天堂 | 国产精品一区二区a| 亚洲区国产区| 日韩午夜电影av| 欧美jizz19性欧美| 亚洲夫妻自拍| 亚洲美女91| 欧美精品一区二区精品网| 欧美成人黑人xx视频免费观看| 好吊日精品视频| 欧美与欧洲交xxxx免费观看| 欧美在线视频观看免费网站| 国产精品乱人伦中文| 中文一区字幕| 午夜精品在线看| 国产欧美在线看| 久久成人av少妇免费| 久久影视精品| 亚洲激情在线观看| 欧美日韩高清在线播放| 日韩视频在线播放| 亚洲欧美在线免费| 国产一区二区三区在线观看免费视频 | 午夜影视日本亚洲欧洲精品| 欧美日韩妖精视频| 亚洲视频在线观看视频| 久久av一区二区三区亚洲| 国产亚洲一级| 玖玖综合伊人| 99伊人成综合| 久久国产精品黑丝| 在线看片第一页欧美| 欧美国产日本韩| 一区二区三区国产盗摄| 久久国产手机看片| 亚洲盗摄视频| 国产精品成人v| 欧美主播一区二区三区美女 久久精品人| 另类专区欧美制服同性| 日韩视频精品| 国产亚洲精品高潮| 欧美国产日韩一区二区在线观看 | 久久久精品国产免大香伊| 亚洲成在人线av| 欧美午夜在线视频| 久久九九久精品国产免费直播| 亚洲国产经典视频| 欧美怡红院视频| 亚洲欧洲精品一区二区| 国产精品一级久久久| 免费亚洲一区二区| 亚洲女人天堂成人av在线| 欧美国产免费| 久久精品国产一区二区电影| 亚洲精品一区二区三区av| 国产亚洲女人久久久久毛片| 欧美成人综合在线| 欧美亚洲三级| 99热精品在线观看| 欧美成人中文字幕| 久久久www成人免费无遮挡大片| 亚洲国产精品久久91精品| 国产精品久久久久9999高清| 蜜臀av一级做a爰片久久| 亚洲综合丁香| 一区二区国产精品| 亚洲黄一区二区| 久久综合久久综合久久| 亚洲欧美日韩国产成人| 一区二区三区日韩精品视频| 亚洲国产另类久久久精品极度| 国产视频亚洲精品| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ入口 | 欧美成人免费视频| 久久精品在线免费观看| 午夜国产精品影院在线观看| 一二三区精品| 日韩亚洲欧美成人一区| 亚洲国产日韩欧美一区二区三区| 国产亚洲精品v| 国产精品网红福利| 国产精品夫妻自拍| 欧美色精品在线视频| 欧美日本在线视频| 欧美精品七区| 欧美激情亚洲自拍| 欧美精品v日韩精品v韩国精品v| 久久久999国产| 久久久精品欧美丰满| 久久精品电影| 久久免费国产| 免费久久久一本精品久久区| 久热这里只精品99re8久| 久久免费99精品久久久久久| 久久在线视频在线| 你懂的视频欧美| 欧美肥婆bbw| 欧美日韩一卡| 国产精品一二三视频| 国产亚洲高清视频| 激情国产一区| 亚洲精品一二三区| 亚洲午夜视频在线观看| 亚洲欧美在线观看| 久久久www| 亚洲国产精彩中文乱码av在线播放| 欧美黄污视频| 日韩视频在线一区| 亚洲男人的天堂在线| 欧美一区二区三区免费观看| 久久久久www| 亚洲丁香婷深爱综合| 日韩一区二区精品在线观看| 亚洲一级黄色片| 久久久噜噜噜久噜久久| 欧美精品免费在线| 国产日韩欧美二区| 最新中文字幕一区二区三区| 亚洲欧美99| 欧美不卡高清| 亚洲一区二区3| 久久在线精品| 国产精品久久波多野结衣| 国产一区激情| aa级大片欧美三级| 久久久99久久精品女同性| 亚洲日韩欧美一区二区在线| 亚洲欧美国产视频| 欧美成ee人免费视频| 国产精品欧美久久久久无广告| 在线看国产一区| 欧美在线视频观看| 亚洲精品欧美一区二区三区| 久久福利毛片| 国产精品外国| 亚洲午夜91| 亚洲激情视频网站| 久久精品亚洲| 国产精品久久久久久亚洲调教|