Assembly WinDbg e .Net x64: procedura dettagliata per il raggiungimento di un punto di interruzione in una sorgente C #

Sto avendo tempi molto duri con WinDbg per tracciare un semplice riferimento a un object in un’app C # Forms. Ho trovato un bellissimo tutorial di Chris Lovett: GCRoot Demo sull’uso di “SOS” nella finestra immediata di VS
Sfortunatamente, sto eseguendo il debug di un’app x64 e la ricompilazione della mia app in 32-bit influenzerà le condizioni di test che sono disposto a ricreare.

Cercando di caricare SOS nei risultati di un assembly x64, come previsto, nel seguente errore:

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

Quindi, visto che WinDbg sembra gestire x64, questo è il modo migliore per me.
Tuttavia, farlo funzionare con il codice gestito non è un compito semplice.
Mettendo un punto di interruzione semplice nei risultati della sorgente allegata, non sorprendentemente, nel seguente errore:

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

Questo è coerente con le linee guida fornite da Naveen Srinivasan.on il suo Blog
Tuttavia, quando provo ad usare le soluzioni alternative “sxe ld” / “.loadby sos” / “.load sosex” suggerite nella stessa pagina web, ottengo il seguente errore:

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

Quindi immagino che questi ultimi comandi siano anche correlati a SOS

Ho anche provato a seguire un post più vecchio di Eran Sandler che spiega esattamente come procedere per impostare un punto di interruzione in WinDbg per il codice gestito. Ma sospetto che il comando name2ee che sta usando sia “SOS” specifico, rendendolo quindi piuttosto inutilizzabile nel mio caso (sto ricevendo lo stesso tipo di errore LoadLibrary).

Sono davvero confuso e indifeso qui. Sento di sbattere contro i muri in qualsiasi direzione prenda. Sono a due pollici dal dover rinunciare e ricompilare l’intera App in 32-bit per eseguire il debug, dato che ho già perso quasi 2 giorni lavorativi su questo.

Tutto questo è solo il primo passo verso ciò che voglio raggiungere, ovvero tracciare tutti i riferimenti a un object “Trackee” in un’App più complessa, utilizzando gcroot.

Di te per il tuo aiuto.

Codice di esempio fittizio: 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 } } } 

RISPOSTA: procedura dettagliata

1 – “loadby sos.dll clr” rende ansible chiamare tutte le cose SOS. (incluso il comando “name2ee” per seguire i passi di Eran Sandler.)
2 – Il seguente comando posiziona efficientemente un breakpoint nel codice gestito di un metodo. Esempio !bpmd DebugTEst.exe DebugTest.Form1.button1_Click
3 – Non riesco ancora ad avere un vero comportamento di debugger visivo poiché il punto di interruzione viene colpito logicamente come mostrato nella finestra di comando, ma non visivamente nella finestra di origine.
4 – Interpretando il Trackee di un tipo specifico ( MyString, per esempio ) sono stato in grado di tracciare l’indirizzo dell’object usando
!DumpHeap -type myString che fornisce la seguente uscita:

  Address MT Size 0000000002bd33e0 000007ff000581d0 24 

5 – Quindi dopo aver eseguito un load vgcroot e !vgcroot 0000000002bd33e0 C:\graph.dgml sono riuscito a trovare e visualizzare tutti i riferimenti al mio Trackee.