23 Temmuz 2020 Perşembe

WinDBG ile Dump Analizi

Merhaba Arkadaşlar,

Daha önceki yazılarımda envai çeşit dump alma yöntemini paylaşmıştım. Şimdi ise aldığımız bu dump'ları çok kısa nasıl inceleyebileceğimize bakalım. Burada her şeyiyle dumpı analiz etmekten bahsetmiyorum. Onu yapmak başlı başına bir sanat. Ciddi bir tecrübe ve pratik gerektiriyor(ben de çoğunuz gibi bu konuda guru değilim, kendime de söylüyorum bu kısmı=) ). Burada daha ziyade konsept olarak ve belli komutlarla neler yapılabilir ona değineceğim. 

WinDBG tool'u ile almış olduğumuz dump'ı inceleyeceğiz. Dump'ı her önüne gelene vermemenin ne kadar öenmli olduğuna da değineceğiz, subliminal mesaj olarak. =)
Uygulamayı açıyoruz öncelikle, File sekmesinden, Open crash dump tıklanır. Ve dump'ınızı burdan verirsiniz.(benim dump adına takılmayın, full dump almakta tereddüt ettiğim bir andı=) )


Burada aldığınız dump ile, dump aldığımız sunucu ile de ilgili bazı bilgileri görebiliyoruz. 
System Uptime: uygulama sunucunuzun ne kadar süredir ayakta olduğunu gösterir. Bu süre çok uzunsa, demek ki uzun süredir sunucu restart almamış. Atıyorum sunucu 120 gündür restart görmediyse, son 4 aylık patch'leri de geçilmediğini anlayabiliriz. Ve kötü niyetli kişiler bunu kullanır.
Process Uptime: Process'in ne kadar süredir ayakta olduğudur. Bu süre çok uzunsa, process'in recycle edilmediğini gösterir. IIS dump'ı ise bu, application pool recycle'ı düşünmek gerektiğini gösterebilir. Genelde günde 1 defa recycle geçilmesi best practise olarak geçer.
Symbol search path alanı boş gelmiş. Kısaca Symbol şudur: uygulamalar, işletim sistemi ile vs iletişim kurduğunda, ki bildiğiniz üzere bu makina diliyle oluyor, dll veya exe gibi dosya yarattığında bir de pdb dosyası oluşturur. Symbol tam da budur. Symbol içinde assembly için debugging sembolleri vardır. Windbg'nin dumpı çözebilmesi için global, Microsoft'un sitesinden bu sembolleri indirmesi gerekmektedir.

File sekmesi altından, Symbol File Path deyip, Symbol Path'e tıklanır. Sonrasında SRV*https://msdl.microsoft.com/download/symbols yazılır. Artık symboller de hazır.
.sympath yazarak symbollerin nereden alındığını da görebiliyoruz.



.reload yazarak ilgili adresten cache'imize çekebiliriz de bu sembolleri:

!analyze -v komutu ile crash analizi başlatılabilir.

Analiz sonrası !threads komutu ile dump alınan sistem üzerindeki aktif threadlerin durumunu görebiliyoruz.

En soldaki 164-166 olanlar threadIDlerdir. ThreadID alanında XXX yazanlar ise, işini bitiren threadlerdir ve dump aldığımız esnada henüz Garbage Collector işini tamamlamamıştır. 

Mex diye bir extension var debuggingi incelemek için. Onu kurabiliriz.

!us komutu ile unique stacklerin listesini verir. Çalışan threadler işini yaparken, biz dump alarak, onları böldük. Onlar da işlerini bırakıp bize dump verdi. 
36 stack(s) with 203 threads displayed (203 Total threads) à 36 farklı iş yapan thread var. 203 total treadin.

Şimdi bir threade bakalım mesela.

~(tilda): thread demektir.
87s: 87 nolu threadi select ediyor. Onu çağırıyor yani.

!clrstack2 :  .net stacki döker.(mex ile gelen komuttur)

0:000> ~87s

eax=00000000 ebx=00000001 ecx=00000000 edx=00000000 esi=00000001 edi=00000001

eip=7741c8ac esp=39b2ec10 ebp=39b2ed98 iopl=0         nv up ei pl nz ac po nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212

ntdll!NtWaitForMultipleObjects+0xc:

7741c8ac c21400          ret     14h


0:087> !clrstack2  à artık başında a görüldüğü gibi 87 nolu thread'e geçti.

DbgId ThreadId Apartment Kind CLR              GC Mode    GC Suspending?

   87    11fc4 MTA            v4.0.30319.34209 Preemptive no

 

MonitorWait

-----------

Method          XXXXXXX.Esb.Queue.QueueManager.GetNextMessage()

Monitor Address 0x0000000020421088

 

SP       IP       Function                                                                                                                                   Source

39b2ef7c 00000000 GCFrame                                                                                                                                   

39b2f02c 00000000 HelperMethodFrame_1OBJ [System.Threading.Monitor.ObjWait(Boolean, Int32, System.Object)]      à alttaki de bunu çağırmış.                                            

39b2f0b0 72625d16 System.Threading.Monitor.Wait(System.Object, Int32, Boolean)     à alttaki getnextmessage methodu bir yerde threadslep yapıyor; bekliyor yani. 87 nolu thread bekliyor.                                                                        

39b2f0c0 39006df7 XXXXXX.Esb.Queue.QueueManager.GetNextMessage()                                                                                         

39b2f104 39006ff5 XXXXXXXX.Esb.Queue.WorkerThread.Run()                                                                                                     

39b2f128 7259ab43 System.Threading.ThreadHelper.ThreadStart_Context(System.Object)                                                                          

39b2f134 725ada07 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)

39b2f1a0 725ad956 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)        

39b2f1b4 725ad921 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)        à http contextin içine konup istek gelir soaptan vs. burda contextin içi kounuyor.         

39b2f1cc 7259aacc System.Threading.ThreadHelper.ThreadStart()       à threadim burda başlar.                                                                                         

39b2f320 00000000 GCFrame                                                                                                                                   

39b2f500 00000000 DebuggerU2MCatchHandlerFrame                                                                                                              

39b2f56c 00000000 ContextTransitionFrame                                                                                                                     

39b2f6f4 00000000 DebuggerU2MCatchHandlerFrame



System'den ziyade XXXXX ile başlayanlar önemli. Bunları ben maskeledim. Kütüphaneler vs belli olmasın diye. =) Sizinkiler ne ise onu yazar.



!name2ee * XXXXXX.Esb.Queue.WorkerThread.Run        komutu ile bu classın bu methodunu tüm kütüphanelerde ararız.

 

--------------------------------------

Module:      3647869c   à esb.dll’in memorydeki adresi

Assembly:    XXXXXX.Esb.dll

Token:       0600d745

MethodDesc:  38f4b56c

Name:        XXXXX.Esb.Queue.WorkerThread.Run()

JITTED Code Address: 39006fd0

--------------------------------------

 

!savemodule 3647869c C:\Temp\XXXXX.Esb.dll     à bu komut ile esb.dll’i Temp dizinine oluşturmuş oluruz.


Yani dump dosyasından dll'i elde etmek de mümkün. 

Dediğim gibi temel komutlara kısaca baktık. Yoksa dump analizi başlı başına bir alan.

Birazdan görüşürüz.


Hiç yorum yok: