"cdb.exe" için debugger script'leri geliştirme

 Merhabalar,

Önceki bir makalemde, debugger ("Windbg.exe") kurulumunun nasıl yapılacağını görmüş ve "SOS.dll" gibi debugger eklentilerine değinmiştik. "Windbg.exe", "Debugging Tools for Windows" kurulum paketi ile birlikte geliyordu ve bu pakette ilgili "Windows SDK"sının alt paketlerinden biri idi.

"Windbg.exe" ile birlikte aynı kurulumda gelen "cdb.exe", aslında bizim daha alt seviye "debugger"ımız ve arka planda "dbghelp.dll" kullanıyor. Bu yazımda "cdb.exe" kullanarak debugger komutlarını nasıl çalıştırabiliriz, bunu anlatmaya çalışacağım.

Örneğin, "System.Environment.Exit(Int32)" fonksiyonunun hangi ".net" modülünden çağrılıdığını bulmaya çalışıyorsunuz. Bu durumda "cdb.exe"ye aşağıdaki komutları sıra ile çalıştırtmanız gerekmekte:

.logopen c:\dumps\dbglog.txt;
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll
!bpmd mscorlib_ni System.Environment.Exit
g
kL
.logclose;
q

Yukarıdaki komutların çıktıları, ".logopen" ve ".logclose" çağrıları arasında "c:\dumps\dbglog.txt" isimli bir dosyaya kopyalanıyorlar. Yukarıda görüldüğü gibi ilgili "framework"e ait "SOS.dll"ini yükleyip devamında yakalamaya çalıştığımız fonksiyona bir "breakpoint" koyuyoruz. "Breakpoint"e gelindiğinde ise bu fonksiyonu çağıran "callstack"i "kL" komutu ile döküyoruz. Bu sayede log dosyasında aşağıdaki gibi, çağrıyı yapan "callstack"i görebilirsiniz.

0:000> kL
ChildEBP RetAddr 
...
005bef60 73ab3ed1 clr!SystemNative::Exit+0x4f
005bef98 009f0385 mscorlib_ni!System.Environment.Exit(Int32)+0x41
005befa8 5990113e FormsAppforEnvExit!FormsAppforEnvExit.Form1.button1_Click(System.Object, System.EventArgs)+0x25
005befc0 598ffaf0 System_Windows_Forms_ni!System.Windows.Forms.Control.OnClick(System.EventArgs)+0x62
005befd0 59ec1f20 System_Windows_Forms_ni!System.Windows.Forms.Button.OnClick(System.EventArgs)+0x80
...

Bu ve bunun gibi "script"ler birbirinden farklı birçok durum için oluşturulabilir. Birkaç örnek vermek gerekirse, bir "script" yazarak tüm "first chance CLR Exception"larını loglayabilir yada başka bir "custom event"ın ne kadar sıklıkla tetiklendiğini görebilirsiniz. Yada o anda bir "dump" dosyası oluşturabilirsiniz. Aslında bu tip "script"ler, "Live debugging" esnasında yapacak olduğumuz işlemleri taslaklar haline getirmekten ibaret.

Yukarıdaki örnek için uygulanması gereken adımlar ise şu şekilde:

#1- Şu klasörleri yaratıyoruz c:\dumps, c:\debuggers
#2- İlgili mimariye göre "Debugging Tools for Windows" yükleyip, "c:\debuggers" klasörüne içeriğini kopyalıyoruz. Nihayetinde bu klasör altında "cdb.exe" bulunuyor olacak.
#3- Yukarıda belirttiğim komutları "catchEnvExitStack.cfg" dosyasına kaydedip, bu dosyayı "c:\debuggers" altına kopyalıyoruz.
#4- Diyelim ki debug edeceğimiz uygulamamızın adı "MyApp.exe" olsun bu uygulamanın "Process ID"sini taskmanager.exe üzerinden yada "tlist.exe" komutu ile buluyoruz.
#7 Admin yetkileri ile bir komut satırı açıp, "c:\debuggers" altına gidiyoruz ve aşağıdaki komutu çalıştırıyoruz.

cdb.exe -cf catchEnvExitStack.cfg -p PID_OF_MyApp.exe

Diyelim ki "MyApp.exe" nin "process ID"si 3256 olsun bu durumda:

cdb.exe -cf catchEnvExitStack.cfg -p 3256

#10 Fonksiyon çağırılana kadar bekliyoruz, problem oluşana kadar ekranda en son “g” komutu görülmeli..
 

#11 Problem oluşunca script aşağıdaki gibi tamamlanıyor ve log yazılıyor. 

 

İyi çalışmalar dilerim,

Mert Öztürk