Click here to Skip to main content
15,400,433 members
Articles / Programming Languages / C++
Posted 25 Sep 2002


161 bookmarked

An Introduction to Debugging in MSVC++ using Pseudoregisters

Rate me:
Please Sign up or sign in to vote.
4.94/5 (79 votes)
24 Nov 20024 min read
Explanation of the debugger pseudoregisters like @ERR, @TIB


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:

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:

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 the following lines after the fopen:

if (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:

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

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

[Table from "Debugging Applications" by John Robbins]


  • John Robbins for his "Debugging Applications" book


This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below. A list of licenses authors might use can be found here.


About the Author

Wouter Dhondt
Web Developer
Belgium Belgium
Wouter got interested in computers and programming at the age of 12 (using a 286 and basic). Several years and an electronics degree later, he started working as a software engineer. In the summer of 2001, Wouter created Fping as an alternative to the windows ping program (just for his own amusement). Amazed by the response / interest, he founded to ensure a better distribution for the tool. Several other applications have been released since...

Comments and Discussions

GeneralMy vote of 4 Pin
Nibu babu thomas13-Dec-10 4:59
MemberNibu babu thomas13-Dec-10 4:59 
GeneralGet a "return value" from a function and format the number Pin
Anipro27-Aug-10 14:38
MemberAnipro27-Aug-10 14:38 
GeneralTo display the last error code as a string... Pin
Paul Sanders (the other one)29-Oct-07 13:14
MemberPaul Sanders (the other one)29-Oct-07 13:14 
GeneralRe: To display the last error code as a string... Pin
Wouter Dhondt21-Aug-08 23:07
MemberWouter Dhondt21-Aug-08 23:07 
GeneralRe: To display the last error code as a string... Pin
Paul Sanders (the other one)21-Aug-08 23:32
MemberPaul Sanders (the other one)21-Aug-08 23:32 
Questiondo not support wince ? Pin
yifengling000022-Oct-07 21:53
Memberyifengling000022-Oct-07 21:53 
GeneralGood Article Pin
Anant wakode30-Jul-06 22:42
MemberAnant wakode30-Jul-06 22:42 
GeneralThank you Pin
Jay Zhu4-Apr-06 23:32
MemberJay Zhu4-Apr-06 23:32 
GeneralAlways Required but never aware Pin
moyeenm30-Nov-04 20:18
Membermoyeenm30-Nov-04 20:18 
GeneralNice article Pin
gangadhar npk12-Jun-03 18:24
Membergangadhar npk12-Jun-03 18:24 
GeneralKooool Pin
Member 6726844-Aug-03 19:09
MemberMember 6726844-Aug-03 19:09 
Generalquick watch question ... Pin
eXplodus26-Mar-03 2:58
MembereXplodus26-Mar-03 2:58 
GeneralRe: quick watch question ... Pin
Andy Pennell7-Apr-03 6:59
MemberAndy Pennell7-Apr-03 6:59 
GeneralRe: quick watch question ... Pin
eXplodus7-Apr-03 20:34
MembereXplodus7-Apr-03 20:34 
GeneralSlight corrections Pin
Andy Pennell25-Mar-03 17:20
MemberAndy Pennell25-Mar-03 17:20 
GeneralRe: Slight corrections Pin
Wouter Dhondt25-Mar-03 21:11
MemberWouter Dhondt25-Mar-03 21:11 
Generalsure,cool Pin
alidiedie21-Feb-03 21:57
Memberalidiedie21-Feb-03 21:57 
GeneralWow! Thanks! Pin
Thomas Haase22-Jan-03 21:29
MemberThomas Haase22-Jan-03 21:29 
Questionnice article and a question? Pin
mansour ahmadian9-Jan-03 23:49
sussmansour ahmadian9-Jan-03 23:49 
AnswerRe: nice article and a question? Pin
Wouter Dhondt10-Jan-03 0:18
MemberWouter Dhondt10-Jan-03 0:18 
AnswerRe: nice article and a question? Pin
klo10-Mar-03 8:31
Memberklo10-Mar-03 8:31 
Generalthis is a wonderful article! Pin
lucy11-Dec-02 7:03
Memberlucy11-Dec-02 7:03 
QuestionVC5? Pin
Anonymous2-Dec-02 6:07
MemberAnonymous2-Dec-02 6:07 
AnswerRe: VC5? Pin
Wouter Dhondt2-Dec-02 21:16
MemberWouter Dhondt2-Dec-02 21:16 
GeneralExcellent article!!! Pin
Nish Nishant25-Nov-02 17:07
sitebuilderNish Nishant25-Nov-02 17:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.