Tuesday, June 14, 2011

DbgEng.lib Part 2- Forcing a Debug Break

Today we had an issue where some drivers weren't getting installed correctly on a vm.  For whatever reason, they were taking upwards of 10 minutes to install, when in the past they've taken less than a minute.  We decided we needed to break into the debugger somewher in that 10 minute window and figure out what was going on.  Unfortunately, the problem didn't repro 100% of the time, and took a great deal of setup.  Fortunately, we already had it all automated- except for the breaking into the debugger part.  I thought to myself, given my last post, I had no choice but to use DbgEng.lib.

Anyway, I thought I'd post the source for a quick little program I wrote that takes the remote settings of the debugger as an argument, causes the debugger to break in, and then exits.  A perfect example of how DbgEng can be useful in everday life.

main.h:

#pragma once
#include <dbgeng.h>
#include <stdio.h>
#include <windows.h>



main.cpp:

#include "main.h"
void Usage()
{
    printf("Usage: BreakIntoDebugger.exe <connection string>\n");
    printf("\texample: BreakIntoDebugger.exe npipe:server=localhost,pipe=vmname");
}
int main(int argc, char* argv[])
{
    printf("BreakIntoDebugger Started\n");
    printf("number of args:%i\n", argc-1);
    for(int i = 1; i < argc; i++)
    {
        printf("argv[%i] = ", i);
        printf("%s\n", argv[i]);
    }
    if(argc < 2)
    {
        Usage();
        return 1;
    }
    HRESULT hr;
    IDebugControl* pControl = NULL;
    IDebugClient* pClient = NULL;
    ULONG status = 0;
    PCSTR pcRemoteOptions((PSTR)argv[1]);
    hr = DebugConnect(pcRemoteOptions, __uuidof(IDebugClient), (PVOID*)&pClient);
    if(FAILED(hr))
    {
        printf("DebugConnect failed");
        return 1;
    }
    hr = pClient->QueryInterface(__uuidof(IDebugControl), (PVOID*)&pControl);
    if(FAILED(hr))
    {
        printf("QueryInterface failed");
        return 1;
    }
  
    hr = pControl->GetExecutionStatus(&status);
    if(FAILED(hr))
    {
        printf("GetExecutionStatus failed");
        return 1;
    }
    if(status == DEBUG_STATUS_BREAK)
    {
        printf("Already Broken in!");
        return 0;
    }
  
    hr = pControl->SetInterrupt(DEBUG_INTERRUPT_ACTIVE);
    if(FAILED(hr))
    {
        printf("SetInterrupt failed");
        return 1;
    }
    printf("successfully broke into the debugger");
}

No comments:

Post a Comment