Why isn’t the !bpmd in sos / windbg not working?
I recently noticed another blog post refer to one of my post. The issue was, sos wasn’t enabling the break-points on non-jitted functions. The classic example being “Main”. Thanks to Steve I have been using sosex and not sos for setting break-points.
From my previous post you can understand how CLR is using clrn/CLRNotificationException to notify sos/sosex on JIT. With this information when I looked at the rotor code, I noticed an interesting member variable “g_dacNotificationFlags”. So I decided to check the value of this variable when using !bpmd from sos and !mbm from sosex.
.if (dwo(mscorwks!g_dacNotificationFlags) = 0) {.echo bp not set } .else {.echo bp set}
It was “0″ when using sos and “1″ when using sosex. Now I had to change the value to “1″ and check if the break-point becomes active when using sos’s !bpmd. FYI I don’t have private symbols and haven’t seen CLR Code. Here is the code to set the value to “1″.
ed mscorwks!g_dacNotificationFlags 00000001
And not to my surprise the !bpmd seems to work for non-jitted function with the above hack. FYI we don’t have to resort to this to get !bpmd to work. If the !bpmd is set after load of mscorjit/clrjit it would work as expected.
I wrote a massively trivial C# class library using the 3.5 framework and compiled it in release mode. I then call that library from a Windows Form application when the user clicks a button.
What I want to do is to break when the Add function is called. When I add the bpmd, it is deferred. The problem I have is that it is never resolved. The odd thing is that if I do “sxe ld” I notice that WinDbg never recieves a load event for the referenced assembly yet I can “!dumpdomain” after it is called and can see the assembly and walk the types. Even after calling the Add function, it is not marked as having been JITTED. Any clues?
namespace ClassLibrary1
{
public class Class1
{
private int _seed;
public Class1(int seed)
{
_seed = seed;
}
public int Add(int number)
{
_seed += number;
return _seed;
}
Richard Watson
April 24, 2011 at 8:57 am
I used the same above sample and I was able to get the sxe ld to work.
If you have referenced the dll before the button load then assembly could have been loaded before and that could be one of the reasons you didn’t get a notification.
Here is my sample that calls the seed function
private void button1_Click(object sender, EventArgs e)
{
var c = new ClassLibrary1.Class1(10);
Console.WriteLine(c.Add(2));
}
and here is my partial output of sxe ld call-stack for ClassLibrary1
27:U 0044e798 7219c5c7 mscorwks!MethodDesc::MakeJitWorker+0x1a8
28:U 0044e83c 720611fb mscorwks!MethodDesc::DoPrestub+0x41b
29:U 0044e894 720613bb mscorwks!PreStubWorker+0xf3
2a:U 0044e8e4 00a9083e 0x00a9083e
2b:M 0044e8fc 64124170 System.Windows.Forms.Control.OnClick(System.EventArgs)(+0×0 IL)(+0×70 Native)
2c:M 0044e938 6411f55a System.Windows.Forms.Button.OnClick(System.EventArgs)(+0×0 IL)(+0x4a Native)
2d:M 0044e948 646b6f34 System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)(+0x7e IL)(+0xac Native)
2e:M 0044e964 64687723 System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)(+0×184 IL)(+0x28f Native)
Notice the MakeJitWorker which is key jit function which is causing the assembly to load.
And what is the output of ?dwo(mscorwks!g_dacNotificationFlags)
Let me know if you need any further help.
Thanks
Naveen
April 26, 2011 at 2:38 pm
Even i tried the same and sxe ld didnt break windbg. Moreover, the modules from the image path are not listed using “lm” command. Any reason why its not coming up? Do i need to configure anything?
Ram
May 24, 2011 at 9:38 am