在 WinDbg 扩展中调用 IDbgConsole.PrintTextToConsole 时出现异常

Exception when calling IDbgConsole.PrintTextToConsole in a WinDbg Extension

我正在尝试用 C# 编写一个 windbbg 扩展。该扩展只是一个非常基本的扩展,应该简单地向控制台打印一条语句,但是当我加载扩展和 运行 命令时,我收到以下错误:

0:005> !testCommand
e0434352 Exception in C:\Users\test\AppData\Local\Dbg\EngineExtensions\WinDbgExtension.dll.testCommand debugger extension.
      PC: 00007ffe`42183b29  VA: 00000000`00000000  R/W: 80070002  Parameter: 00000000`00000000

代码:

using System;
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
using DbgX.Interfaces;
using DbgX.Interfaces.Enums;
using DbgX.Interfaces.Listeners;
using DbgX.Interfaces.Services;
using System.ComponentModel.Composition;

namespace WindbgExt
{
    public class Extension
    {

        [Import]
        private static IDbgConsole _console;

        [DllExport("testCommand")]
        public static void testCommand(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string args)
        {
            _console.PrintTextToConsole("This worked");
        }

        [DllExport("DebugExtensionInitialize")]
        public static int DebugExtensionInitialize(ref uint version, ref uint flags)
        {
            version = DEBUG_EXTENSION_VERSION(1, 0);
            flags = 0;
            return 0;
        }

        private static uint DEBUG_EXTENSION_VERSION(uint Major, uint Minor) => ((Major & 0xffff) << 16) | (Minor & 0xffff);
    }
}

WinDbg 识别扩展名和命令。但是我不知道这个错误是什么意思或者是什么导致了它。非常感谢任何帮助确定导致错误的原因。

编辑 1:
在阅读了一些评论后,我做了一些测试并注释掉 _console.PrintTextToConsole("This worked"); 行停止抛出错误。我希望问题出在接口的声明方式上,但我不知道如何纠正它。我已经尝试将 class 和界面设置为静态,但这并没有纠正这种情况。

编辑 2:
我现在已经尝试声明 IDbgConsole 的一个实例并以我能想到的所有方式调用 PrintTextToConsole 但是所有这些都会产生以下错误。即使将它包装在 try and catch 块中也无济于事,因为不会触发 catch 部分。如果有另一种写入控制台的方法比修复此错误更容易,那也可以作为解决方案。

您在这里混淆了两个概念。有两种 Windbg 扩展:调试器扩展和 UI 扩展。

  • UI 扩展由 WPF shell 自动加载(假设您将它们放在正确的文件夹中)。我写了 a few articles about them 但 API 仍然没有记录。使用 UI 扩展,可以使用 MEF 和 IDbgConsole 等服务,但不能直接与调试器交互(必须找到合适的服务并使用它来发送命令)

  • 调试器扩展在单独的进程中加载​​。它们加载了 .load.loadby 命令。它们允许您直接与调试引擎交互。使用这些扩展,如果您使用本机导出工具,例如 RGiesecke.DllExport,您可以公开新命令。重要的是要理解它们 运行 在一个单独的进程中并且与 UI 完全隔离。 您不能从那里使用 MEF 和 IDbgConsole 等服务。

在您的情况下,您似乎只是想将内容打印到控制台。您可以使用 IDebugControl 对象来实现。编写一个流来包装它并将其设置为控制台输出流更容易,因此您可以只使用 Console.WriteLine。在 ClrMD github 存储库(即 DbgEngStream class)上有一个如何执行此操作的示例:https://github.com/microsoft/clrmd/blob/18c9e1304228d375191b5f805b7a5d9da2ec86ef/src/Samples/WindbgExtension/Common.cs