WinDbg and .Net x64 Assembly : Step-By-Step Walkth

2019-04-14 06:30发布

问题:

I am having very hard times using WinDbg to track a simple object reference in a C# Forms App. I have found a very nice tuto by Chris Lovett : GCRoot Demo on using "SOS" in VS' Immediate Window
Unfortunately, I am debugging an x64 App and recompiling my App into 32-bit will bias the test conditions I am willing to recreate.

Trying to load SOS in an x64 Assembly results, as expected, in the following error :

Error during command: extension C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll could not load (error 193)

So, as WinDbg seems to manage x64, that's the way to go for me.
However, getting it to work with managed code is not a straightforward task.
Putting a simple breakpoint into the attached source results, unsurprisingly, into the following error :

Unable to insert breakpoint 0 at 00000000 010e000f, Win32 error 0n998
"Invalid access to memory location."

This is consistent with the guidelines given by Naveen Srinivasan.on his Blog
However, when I try to use the ” sxe ld” / “.loadby sos” / ”.load sosex" workarounds suggested in that same web page, I get the following error :

The call to LoadLibrary(sos) failed, Win32 error 0n2
The system cannot find the file specified.

So I guess the latter commands are also SOS-related

I have also tried to follow an older post from Eran Sandler which explains exactly how to proceed to set a breakpoint in WinDbg for Managed Code. But I am suspecting the name2ee command he is using to be "SOS" specific, thus making it rather unusable in my case (I am getting same kind of LoadLibrary error).

I am really confused and helpless here. I feel I am bumping on walls whatever direction I take. I am two inches far from giving up and recompiling the whole App into 32-bit to debug it, as I've already lost almost 2 working days on this.

All this is only the first step towards what I want to achieve, which is to track all the references to a "Trackee" object in a more complex App, using gcroot.

Than you for your help.



Dummy Sample code : DebugTest.cs :

namespace DebugTest
{    
    public partial class Form1 : Form
    {
        String Trackee;
        public Form1()
        {
            InitializeComponent();
            Trackee = "Where is Charlie";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            label1.Text = Trackee; // << Trying to put a breakpoint here
        }
    }
}


ANSWER : Walkthrough

1 - "loadby sos.dll clr" makes it possible to call all SOS stuff. (including "name2ee" command to follow Eran Sandler's steps.)
2 - The following command puts a breakpoint efficiently into the Managed code of some method. Example: !bpmd DebugTEst.exe DebugTest.Form1.button1_Click
3 - I am still unable to have a real visual debugger behavior as break point is hit logically as shown in the command window, but not visually in source window.
4 - By affecting to Trackee a specific Type (MyString, for ex.) I was able to track the Object's adress using
!DumpHeap -type myString which give the following ouput :

  Address               MT              Size
0000000002bd33e0 000007ff000581d0       24 

5 - Then after performing a load vgcroot and !vgcroot 0000000002bd33e0 C:\graph.dgml I was able to find and visualize all the references to my Trackee.