调试器使用的调试引擎信息

9
在Visual Studio中,如果您想要将调试器附加到任何进程上,则可以选择一些特定的引擎(代码类型)或一组您希望使用的引擎:

enter image description here

在你选择任何引擎和进程之后,如果你点击Attach按钮,调试器附加操作就会开始。然后也会触发调试相关的事件。IDebugEventCallback2::Event可以用来获取这些事件(例如提取调试器实际附加到的进程的名称):

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);
        //...
    }
}

有没有类似的方法可以获取已选择的引擎的一些信息?

更新:稍微详细一些的代码:

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) { /*...*/ }
}

和用法:

var debugger = GetService(typeof(SVsShellDebugger)) as IVsDebugger;
var hunter = new DebugEventsHunter(debugger);
hunter.Start();

很难理解你是如何错过下一步的,调用IDebugProcessCreateEvent2.GetEngine()。出了什么问题? - Hans Passant
@Hans Passant:如果您指的是IDebugEngineCreateEvent2::GetEngine(),我已经尝试使用它,但没有成功。请检查更新后的问题以验证我做错了什么(顺便说一句:我正在使用VS2013,如果有任何区别,请告诉我)。 - jwaliszko
1个回答

3
当调试引擎启动进程或附加到现有进程时,它会及时发送IDebugLoadCompleteEvent2事件。您可以使用此事件确定选择了哪些调试引擎进行调试。 编辑: 要确定调试引擎的名称,您可以使用上述事件中包含的IDebugProgram2实例,并调用IDebugProgram2.GetEngineInfo方法。此方法提供调试引擎的名称和ID。请注意,调试引擎的名称可能与您在调试器对话框中看到的不一样,在这种情况下,您需要使用自己的映射实现将此方法返回的规范名称转换为“友好”名称。

实际上,由于会触发许多不同的调试事件,因此在Event函数中,我可以观察debugEvent参数,并等待它变成IDebugLoadCompleteEvent2类型。这是可能的。但是如果我捕获了此事件(就像我捕获了IDebugProcessCreateEvent2一样),那么如何获取有关引擎的信息呢? - jwaliszko
我以为你在问哪些引擎被附加了?只有调试引擎被附加才会发送该事件。 - Sam Harwell
我的问题是我正在编写一个小的VS插件,我需要两个信息:我们选择要附加的进程名称以及我们选择的代码类型名称。如果您附加到任何进程插件,它只会等待IDebugProcessCreateEvent2事件,提取进程名称(如问题中所示)并将其存储在文件中(以供以后使用)。不幸的是,我不知道如何获取已选择要进行调试的代码类型。 - jwaliszko
我希望它们被存储在与进程名称相同的文件中。我需要这样做是因为该插件稍后可以重新附加到我们之前附加到的这些进程(使用保存在文件中的名称)。缺点是我的插件始终使用“managed”引擎进行附加:var engines = new[] { transport.Engines.Item("managed") }; process.Attach2(engines)。如果我能够使用先前使用过的代码类型(引擎)重新附加,那将非常有帮助。 - jwaliszko
对不起,但我仍然不理解。您提到“您可以使用此事件确定选择了哪些调试引擎进行调试”,但是如何确定呢?我需要名称,例如“Native”或“Managed”或“Managed/Native”等。通过查看上面的代码,您能告诉我如何实现获取引擎名称的逻辑吗? - jwaliszko
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接