Reputation: 149
I am trying to write a WinDbg extension command and running into some problems. I started with this project and tried to modify it to supply a custom command in the debugger.
However when I run TestCommand
I get the following error.
The command was: !TestCommand this is a test0:000> !TestCommand this is a test
No export TestCommand found
The full code I have is below. I have attempted adding the [Export]
modifier to the TestCommand function however this has not rectified the situation. How would I get WinDbg to recognize the command?
Full extension code:
using System.ComponentModel.Composition;
using DbgX.Interfaces;
using DbgX.Interfaces.Enums;
using DbgX.Interfaces.Listeners;
using DbgX.Interfaces.Services;
using DbgX.Util;
namespace WinDbgExt.LoadSos
{
[Export(typeof(IDbgCommandExecutionListener))]
[Export(typeof(IDbgStartupListener))]
public class ToggleSosViewModel : IDbgCommandExecutionListener, IDbgStartupListener
{
private bool _engineLoaded;
[Import]
private IDbgConsole _console;
[Import]
private IDbgEngineState _engineState;
public void OnCommandExecuted(string command)
{
if (command.StartsWith("!TestCommand"))
{
TstCommand(command);
}
}
public void TestCommand(string command)
{
_console.PrintTextToConsole("The command was: " + command);
}
public void OnStartup()
{
}
}
}
As a bonus question I need to get a handle for the process that WinDbg is attached to. Is there a simple way to add that to the above extension?
Upvotes: 1
Views: 368
Reputation: 59513
I think there's a misunderstanding. OnCommandExecuted()
is an event listener which invoked when you entered a command in WinDbg. The given UI extension you have compiled will first be notified about the command, then WinDbg will try and actually run the command. Since the command does not exist, it will respond with the same error message that you get when no UI extension is loaded.
If I understand correctly what you want, then you're trying to implement a WinDbg extension (not a UI extension) that implements the command !TestCommand
. That's usually a totally different approach.
In the given source code, you find a "regular" WinDbg extension in the WinDbgScriptRunner.x64 and WinDbgScriptRunner.x86 projects. There you can see that you need
[DllExport("compileandrun")]
on a method to make a method a !
-command.
But, unfortunately, they fail with an exception:
0:000> !compileandrun
e0434352 Exception in C:\Users\T\AppData\Local\dbg\UIExtensions\CsharpScriptRunner-x64\WindbgScriptRunner.dll.compileandrun debugger extension.
PC: 00007ff9`c183a799 VA: 00000000`00000000 R/W: 8013150c Parameter: 00000000`00000000
I've added that as issue #4 on their Github repository.
So, yes, I understand that implementing extensions is a bit tricky if you want to do it in C#. So, how could you misuse the given functionality and implement commands?
The only command which has no side effects is probably the comment command:
* this is a comment
You could repurpose this to
*!TestCommand
and the code for that is
if (command.StartsWith("*!TestCommand"))
{
_console.PrintTextToConsole("My command was invoked! Yay!\r\n");
return;
}
The output is also a bit awkward, since your code is executed before the actual command is written into the window:
(4b34.1954): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ff9`c3dd119c cc int 3
My command was invoked! Yay!
0:000> *!TestCommand
I'm not familiar with writing UI extensions for WinDbg Preview, so I'm not sure how far you can get with this approach and whether you can fix the order of output.
Upvotes: 1