9

In Visual Studio, if you want to attach debugger to any processes, you have the possibility to select some specific engine (code type) or set of engines you would like to use:

enter image description here

Next (after you selected any engines and processes), if you click Attach button, the debugger attach operation is started. Then also debug-related events are fired. IDebugEventCallback2::Event can be used to grab such events (and e.g. extract the names of the processes debugger is actually attaching to):

public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program,
                 IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, 
                 uint attributes)
{
    if (debugEvent is IDebugProcessCreateEvent2)
    {
        string processname;
        if(process != null)
            process.GetName((uint) enum_GETNAME_TYPE.GN_FILENAME, out processname);
        //...
    }
}

Is there any similar way to get some information about the engines which have been chosen?

UPDATE: a bit more detailed code:

public class DebugEventsHunter : IVsDebuggerEvents, IDebugEventCallback2
{
    private readonly IVsDebugger _debugger;
    private uint _cookie;

    public DebugEventsHunter(IVsDebugger debugger) { _debugger = debugger; }

    public void Start()
    {
        _debugger.AdviseDebuggerEvents(this, out _cookie);
        _debugger.AdviseDebugEventCallback(this);
    }   

    public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program,
                     IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes)
    {
        if (debugEvent is IDebugProcessCreateEvent2)
        {
            // get process name (shown before) 
        }               
        if (debugEvent is IDebugEngineCreateEvent2)
        {
            // why execution flow never enters this scope?
            IDebugEngine2 e;
            ((IDebugEngineCreateEvent2)debugEvent).GetEngine(out e);
        }
        // engine parameter is also always null within this scope
        return VSConstants.S_OK;
    }

    public int OnModeChange(DBGMODE mode) { /*...*/ }
}

and the usage:

var debugger = GetService(typeof(SVsShellDebugger)) as IVsDebugger;
var hunter = new DebugEventsHunter(debugger);
hunter.Start();
jwaliszko
  • 16,942
  • 22
  • 92
  • 158
  • Hard to see how you missed the next step, call IDebugProcessCreateEvent2.GetEngine(). What went wrong? – Hans Passant Mar 23 '14 at 01:14
  • @Hans Passant: If you mean `IDebugEngineCreateEvent2::GetEngine()` I've tried to use it, but without any success. Please check the updated question to verify what I've done incorrectly (btw: I'm using VS2013 it this makes any difference). – jwaliszko Mar 24 '14 at 10:51

1 Answers1

3

When a debug engine launches a process or attaches to an existing process, it will send the IDebugLoadCompleteEvent2 event in a timely manner. You can use this event to determine exactly which debug engines were selected for debugging.

Edit: To determine the name of the debug engine, you can use the IDebugProgram2 instance that is included with the above event, and call the IDebugProgram2.GetEngineInfo method. This method provides the name and ID of the debug engine. Note that the name of the debug engine may not match what you are used to seeing in the debugger dialogs, in which case you will need to convert the canonical name returned by this method to a "friendly" name using your own mapping implementation.

Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • Indeed, due to the fact that a bunch of various debug events are fired, inside the `Event` function I can watch the `debugEvent` parameter, and wait when it will be of `IDebugLoadCompleteEvent2` type. It happens. But if I catch this event (just like I catched `IDebugProcessCreateEvent2`), how to get information about the engines then? – jwaliszko Mar 26 '14 at 09:57
  • I thought you were asking about which engines attached? Only debug engines which did attach send that event. – Sam Harwell Mar 26 '14 at 10:50
  • My problem is I'm writing small VS plugin and I need 2 information: what are the names of the processes we have selected to be attached, and what are the names of the code types we have chosen. If you attach to any process plugin just waits for `IDebugProcessCreateEvent2` event, extracts process name (as shown in a question) and stores it in a file (to be later used). Unfortunately I have no idea, how to get this code types, which had been chosen to be debugged through. – jwaliszko Mar 26 '14 at 11:21
  • I would like them to be stored in the same file as processes names. I need it because this plugin is later able to re-attach to this processes we have been attached to previously (using theirs names saved in a file). The drawback is my plugin always attaches using `managed` engine: `var engines = new[] { transport.Engines.Item("managed") }; process.Attach2(engines)`. It would be really helpful, if I could re-attach using this exact code types (engines), which has been used before. – jwaliszko Mar 26 '14 at 11:22
  • @JaroslawWaliszko I edited my post; if you need more information you're going to need to be more clear about *exactly* what information you need. – Sam Harwell Mar 26 '14 at 12:01
  • Excuse me but I still do not understand. You noted that "you can use this event to determine exactly which debug engines were selected for debugging", but how? I need the name, for example "Native" or "Managed" or "Managed/Native", etc. Looking at the code above, could you tell me how to implement the logic able to get the engine name? – jwaliszko Mar 26 '14 at 12:13
  • @JaroslawWaliszko I edited my post to include information about obtaining the *name* of the debug engine which attached. – Sam Harwell Mar 26 '14 at 12:43
  • Thanks. You saved me a lot of time which I really appreciate. – jwaliszko Mar 26 '14 at 12:57