Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / C++
Article

Is The Debugger Attached?

Rate me:
Please Sign up or sign in to vote.
4.96/5 (12 votes)
22 Oct 20013 min read 143.4K   672   31   25
Take different actions depending on whether a debugger is attached to your process.

Introduction

Is The Debugger Attached? As a very big part of my work is being a bugslayer, I tend to have a need for more debugging or debug support code in my projects. This article's code of substance is just one small function with effectively about 13 lines of code. Seems rather insignificant, but it has been very useful to me as a person who does a lot of debugging, and of course, that I even came to writing this function was interesting in itself.

Details

The function is called IsDebuggerAttached(). As the name implies, it returns a BOOL indication if a debugger is attached to the process. This was developed on and for Windows NT 4.0, and also works on Windows 2000. I do not know if it will work on Win9x as internal Windows structures differ. I will now go into some example reason(s) I had the need for this, and how it might help others who might have such needs as well.

One of the first things I consider one of the pillars of good programming practices is the validation and verification of parameters coming into a function. More importantly, the validation of pointers. I've had a steady supply of 'business' due to the encounters of the lack of such practices in my last few years of software engineering. There are situations where parameters coming into a function should always be valid. In such a situation, the standard things to do is to check the parameters for validity via ASSERT's. This is perfect for parameters that should never fail the assertion. The great thing about the assertions is that it gives you the option to break into the debugger. In the case of release builds, this is not available as the ASSERT's evaluate to nothing.

There were situations that I decided that I wanted to take different actions depending on whether a debugger was attached to my process or not. If there was no debugger attached, I had my code either popup a message box on a seriously bad condition, or to output a debug string, and quietly continue on it's way if it's possible. However, I also wanted it to be able to break at the spot of the erroneous condition if a debugger was attached. And obviously, I didn't want to build one version of the code that popped up a message box and/or output a debug string, and another version that did a DebugBreak(). Also, if you called a DebugBreak() and a debugger is not attached to you process, the system would popup a nasty dialog indicating a debug break exception.

All that being said, this was clearly what I wanted :

if (Big_Bad_Error)
{
    if (Debugger_Is_Attached)
    {
        Break_Into_Debugger;
    }
    else
    {
        Say_Something;
    }
}

Here is the code for the function IsDebuggerAttached() :

BOOL IsDebuggerAttached()
{
    DWORD dw;


    __asm
    {
        push eax    // Preserve the registers
        push ecx
        mov eax, fs:[0x18]  // Get the TIB's linear address
        mov eax, dword ptr [eax + 0x30]
        mov ecx, dword ptr [eax]    // Get the whole DWORD
        mov dw, ecx // Save it
        pop ecx // Restore the registers
        pop eax
    }


    // The 3rd byte is the byte we really need to check for the
    // presence of a debugger.
    // Check the 3rd byte
    return (BOOL)(dw & 0x00010000 ? TRUE : FALSE);

}

This is a dig into the Thread Information Block (TIB) of the process to check if a debugger is attached. And for those who don't already know, the FS register points to the current thread's TIB. Needless to say, coming to this involved a fair amount of disassemblies of Windows while in the debugger. Following, is code from the sample application for this article. It's an MFC dialog app where the test is done in the OnOK() handler :

void CDebuggerDlg::OnOK() 
{
    LPBYTE lpBuffer = (LPBYTE)0x80000000;


    // Give it a bogus buffer that will crash it for sure
    ReadMemory(lpBuffer, 1024);

}

BOOL CDebuggerDlg::ReadMemory(LPVOID lpBuffer, 
                              DWORD dwSize)
{
    // Validate the buffer
    if (IsBadWritePtr(lpBuffer, dwSize))
    {
        // This is bad! Must say something!
        if (IsDebuggerAttached())
        {
            // So we'll break into the debugger
            __asm   int 3

            // If you don't mind the function call overhead, 
            // you can call DebugBreak();
            // instead...
        }
        else
        {
            MessageBox(
                "CDebuggerDlg::ReadMemory() : "
                "Bad output buffer : lpBuffer!");
        }

        return FALSE;
    }


    // Well, we're not really gonna write anything to the buffer,
    // it's just a demo ;)
    return TRUE;

}

Well folks, I hope that this technique may be of use to some of you out there.

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhy do you want to save the general registers? Pin
zhzhtst1-Oct-07 16:43
zhzhtst1-Oct-07 16:43 
AnswerRe: Why do you want to save the general registers? Pin
Ganoes Paran8-Jun-09 12:25
Ganoes Paran8-Jun-09 12:25 
GeneralWindows API has a function for this Pin
nobot08-Jan-07 7:52
nobot08-Jan-07 7:52 
GeneralRe: Windows API has a function for this Pin
Artemis8-Jan-07 15:59
Artemis8-Jan-07 15:59 
GeneralRe: Windows API has a function for this Pin
Ganoes Paran8-Jun-09 12:26
Ganoes Paran8-Jun-09 12:26 
GeneralGreat ! Pin
Max235119-Oct-06 4:27
Max235119-Oct-06 4:27 
GeneralRe: Great ! Pin
Artemis19-Oct-06 16:41
Artemis19-Oct-06 16:41 
QuestionDoes it work for XP and 2K3? Pin
morntide21-May-06 21:14
morntide21-May-06 21:14 
QuestionHow to send parameters to a attached Function Pin
Anonymous21-Oct-05 0:54
Anonymous21-Oct-05 0:54 
QuestionHow can I check whether Drwatson is present Pin
Vikas Gandhi4-May-04 19:00
Vikas Gandhi4-May-04 19:00 
Hi ALL
How can I check whether DrWatson is present or not and how can I attach to it. What I mean to say is this I do not want to get a normal windows box ("myexe.exe has enounteread a problem and ....(Send Error Report|Don't Send)) and some how dont send should be pressed by default so that an automatic error dmp is created. Thus we straightway give the control to DrWatson ourselves.

--Vikas
AnswerRe: How can I check whether Drwatson is present Pin
zhzhtst1-Oct-07 16:35
zhzhtst1-Oct-07 16:35 
GeneralIsDebuggerPresent() not in windows 95 Pin
30-Oct-01 3:22
suss30-Oct-01 3:22 
GeneralRe: IsDebuggerPresent() not in windows 95 Pin
Artemis15-Nov-01 0:44
Artemis15-Nov-01 0:44 
GeneralDebugging Pin
24-Oct-01 3:14
suss24-Oct-01 3:14 
GeneralRe: Debugging Pin
Artemis24-Oct-01 21:10
Artemis24-Oct-01 21:10 
GeneralRe: Debugging Pin
Darren Schroeder25-Oct-01 15:09
Darren Schroeder25-Oct-01 15:09 
GeneralRe: Debugging Pin
Artemis25-Oct-01 16:11
Artemis25-Oct-01 16:11 
GeneralRe: Debugging Pin
Toby Opferman24-Mar-04 12:19
Toby Opferman24-Mar-04 12:19 
GeneralRe: Debugging Pin
Toby Opferman24-Mar-04 13:04
Toby Opferman24-Mar-04 13:04 
GeneralIsDebuggerPresent() Pin
23-Oct-01 21:31
suss23-Oct-01 21:31 
GeneralRe: IsDebuggerPresent() Pin
23-Oct-01 22:04
suss23-Oct-01 22:04 
GeneralRe: IsDebuggerPresent() Pin
28-Oct-01 22:06
suss28-Oct-01 22:06 
GeneralRe: IsDebuggerPresent() Pin
Artemis29-Oct-01 15:45
Artemis29-Oct-01 15:45 
General5 Points from Me! Pin
Oz Solomon29-Oct-01 2:34
Oz Solomon29-Oct-01 2:34 
GeneralRe: 5 Points from Me! Pin
Artemis29-Oct-01 15:51
Artemis29-Oct-01 15:51 

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.