Setting a breakpoint in WinDbg for Managed Code
Posted by: Eran Sandler, in Managed Debugging, SOS, WinDbgSetting a break point in native code using WinDbg is easy.
You just run the bp command with the address of the place in memory where you want to place the breakpoint.
Setting a breakpoint in Managed code is a bit trickier.
First of all, WinDbg is a native debugger. Until a method is JITed (JIT as in Just In Time Compilation) it doesn’t even have native code.
The managed assembly might be loaded and mapped, but only after the function in JITed and its native code is generated and loaded it has a place in memory that WinDbg can set a breakpoint on to.
An exception to this are Ahead of Time (AOT) compiled assemblies (assemblies which have a native image generated by ngen.exe).
The steps for setting a breakpoint in Managed code are very simple:
- Find the method table handle of the class.
- Find the method description handle of the method
we want to put a breakpoint on. - Place a breakpoint on the virtual address of method we want
to break into (this will only work on already JITed method whether its from AOT
or they were called once to actually get JITed).
OK, now that we understand the logical steps on how to do it, what do we actually do? (I’m using the same executable from the previous post).
- !name2ee [Assembly name (including extension] [Class Full Namespace]. For example: !name2ee SyncBlkDeadLock.exe SyncBlkDeadLock.Form1. That is the class on which we want to place a breakpoint in one of its methods. The output will look like this.
- !dumpmt -md [MethodTable handle that we got from the previous command]. For Example: !dumpmt -md 0×00a8543c. The output will look like this.
- !dumpmd [MethodDesc handle that we got from the previous command]. For Example: !dumpmd 0×00a853d8. This is the handle for the method
SyncBlkDeadLock.Form1.Thread1Handler().The output will look like this. - In the field “Method VA” we now have th method Virtual Address and we can set a breakpoint on that address.
Quite easy, when you know what you are looking for
Remember, that this only sets a breakpoint on the function entry address, so whenever this function is called it will break (unless you point some kind of a conditional breakpoint).
Enjoy!








Entries (RSS)
June 11th, 2005 at 8:29 am
This is good stuff, Eran.
June 11th, 2005 at 2:46 pm
Thanks Scott!
If you have question about how to perform things or anything else that is related to this topics this blog covers, please, feel free to Email me or post a comment and I’ll be happy to write a post on the matter.
December 12th, 2006 at 8:18 pm
Hi,
Thanks for the info,
By the way, it would be possible to set a breakpoint on a specific code line?
Claudio
December 13th, 2006 at 9:51 am
Claudio,
The main problem with this is that you’ll need to figure out the offset from the method’s virtual address (the actual address containing the jitted code) and that isn’t that easy to correlate back to your C# or VB.NET code
You can disassemble (using !u and the address as parameter) that area and try to figure out where you want to set your breakpoint but it will require some assembly code understanding.
January 12th, 2007 at 10:39 am
[...] !bpmd - Sets a breakpoint on managed code. Setting a breakpoint on a managed code prior to .NET 2.0 was very tricky. I covered this issue in a previous post. In that older post I only covered settings a breakpoint on an already JITed method. Setting a breakpoint on a non-JITed method is even harder. !bpmd will cover all of these aspects.To set the breakpoint all you need to do is provide the module name and method name, or the MethodDesc handle (if you have it). !bpmd also works on generic types. If a breakpoint is set on a generic type it will break on all derived types. [...]
January 12th, 2007 at 11:10 am
[...] Easily set a breakpoint in managed code (and we all know its not that nice to set a managed breakpoint in WinDbg using SOS) using the b[reak] command:b foo.cs:42 - will break in file foo.cs in line 42. b MyClass::MyFunction - will break at the start of MyClass::MyFunction [...]