kiewic
kiewic

Reputation: 16420

Invoke a C# method while paused in WinDbg debugger?

When debugging a C# application using WinDbg, I know how to list the objects of a certain type with !dumpheap. For example:

!dumpheap -stat -type CefSharp.Wpf.ChromiumWebBrowser

Statistics:
              MT    Count    TotalSize Class Name
00007ffa08364978        1           32 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass1f
00007ffa08336f48        1           32 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass22
00007ffa0833fa18        2           64 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass25
00007ffa08364748        4          128 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass28
00007ffa083123c0        1          824 CefSharp.Wpf.ChromiumWebBrowser
00007ffa08361fe0      115         3680 CefSharp.Wpf.ChromiumWebBrowser+<>c__DisplayClass10

Now, I am wondering if I can execute a method of one of these objects using WinDbg. For example, I know this object has a ShowDevTools() method, how can I execute it?

Upvotes: 2

Views: 340

Answers (1)

Thomas Weller
Thomas Weller

Reputation: 59259

TLDR: I've never seen it working until now. A related question is unanswered since 2011. If it would be easily possible, some smart people like Steve Johnson (author of SOSEX) would probably have implemented this in an extension. There's also no such command in netext. The closest there is !weval but it works on members only.


While you have a list of objects now, you'll first need to find the methods that are available at those objects:

!dumpmt -md <MT column from !dumpheap>

To call a method, there's the .call command, but it explicitly states that .NET is not supported:

Managed code cannot be called by this command.

However, .NET is not only managed. After the JIT compiler has processed the IL code, you have native code like in C++.

The !dumpmt -md command already told you whether or not the managed method has already been JITted. There are 3 possibilities:

  1. None: the method has not been jitted
  2. PreJIT: the method has been jitted by NGen
  3. JIT: the method has been jitted

From !dumpmt -md you have a method descriptor, you can use

!dumpmd <method descriptor>

From there, you get a native code address, which could possibly be used for a .call. Unfortunately, the next problem occurs:

0:006> .call 011f0500
                ^ Couldn't resolve '.call 011f0500'

This error message means that WinDbg was unable to resolve the symbols for that method. While you have PDBs for your DLL, the JIT compiler does not produce a PDB for the JITted code.

Therefore you need to specify a prototype as defined in the documentation:

.call /s Prototype Function( Arguments )

Allows you to call the function that is specified by Function even though you do not have the correct symbols. In this case, you must have symbols for another function that has the same calling prototype as the function you are trying to call.

At this point, we have the following open questions:

  • where do I get a good prototype from?
  • what do I do if the method was not JITted?

I'm sorry that this "answer" does not resolve your issue. It may only give some insight on how difficult the situation is.

Upvotes: 1

Related Questions