Aracılığıyla paylaş


Kritik Bölümü Görüntüleme

Kritik bölümler çeşitli yöntemlerle kullanıcı modunda görüntülenebilir. Her alanın tam anlamı, kullandığınız Microsoft Windows sürümünün sürümüne bağlıdır.

Kritik Bölümleri Görüntüleme

Kritik bölümler !ntsdexts.locks uzantısı, !critsec uzantısı, !cs uzantısı ve dt (Görüntüleme Türü) komutu tarafından görüntülenebilir.

!ntsdexts.locks uzantısı geçerli işlemle ilişkili kritik bölümlerin listesini görüntüler. -v seçeneği kullanılırsa, tüm kritik bölümler görüntülenir. Aşağıda bir örnek verilmiştir:

0:000> !locks

CritSec ntdll!FastPebLock+0 at 77FC49E0
LockCount          0
RecursionCount     1
OwningThread       c78
EntryCount         0
ContentionCount    0
*** Locked

....
Scanned 37 critical sections

Görüntülemek istediğiniz kritik bölümün adresini biliyorsanız !critsec uzantısını kullanabilirsiniz. Bu, !ntsdexts.locks ile aynı bilgi koleksiyonunu görüntüler. Örneğin:

0:000> !critsec 77fc49e0

CritSec ntdll!FastPebLock+0 at 77FC49E0
LockCount          0
RecursionCount     1
OwningThread       c78
EntryCount         0
ContentionCount    0
*** Locked

!cs uzantısı, adresine göre kritik bir bölüm görüntüleyebilir, kritik bölümler için bir adres aralığında arama yapabilir ve hatta her kritik bölümle ilişkili yığın izlemesini görüntüleyebilir. Bu özelliklerden bazıları tam Windows simgelerinin düzgün çalışmasını gerektirir. Uygulama Doğrulayıcı etkinse, kritik bölüm ağacını görüntülemek için !cs -t kullanılabilir. Ayrıntılar ve örnekler için !cs başvuru sayfasına bakın.

!cs tarafından görüntülenen bilgiler,!ntsdexts.locks ve !critsec tarafından gösterilenden biraz farklıdır. Örneğin:

## 0:000> !cs 77fc49e0

Critical section   = 0x77fc49e0 (ntdll!FastPebLock+0x0)
DebugInfo          = 0x77fc3e00
LOCKED
LockCount          = 0x0
OwningThread       = 0x00000c78
RecursionCount     = 0x1
LockSemaphore      = 0x0
SpinCount          = 0x00000000

dt (Görüntü Türü) komutu, RTL_CRITICAL_SECTION yapısının değişmez içeriğini görüntülemek için kullanılabilir. Örneğin:

0:000> dt RTL_CRITICAL_SECTION 77fc49e0
   +0x000 DebugInfo        : 0x77fc3e00 
   +0x004 LockCount        : 0
   +0x008 RecursionCount   : 1
   +0x00c OwningThread     : 0x00000c78 
   +0x010 LockSemaphore    : (null) 
   +0x014 SpinCount        : 0

Windows XP ve Windows 2000'de Kritik Bölüm Alanlarını Yorumlama

Kritik bölüm yapısının en önemli alanları şunlardır:

  • Microsoft Windows 2000 ve Windows XP'de LockCount alanı, herhangi bir iş parçacığının bu kritik bölüm için EnterCriticalSection yordamını kaç kez çağırdığını (eksi bir) gösterir. Bu alan, kilidi açılmış bir kritik bölüm için -1 ile başlar. EnterCriticalSection çağrısının her biri bu değeri artırır; LeaveCriticalSection çağrısının her biri ise bunu azaltır. Örneğin, LockCount 5 ise, bu kritik bölüm kilitlidir, bir iş parçacığı bunu edinmiştir ve bu kilidi bekleyen beş ek iş parçacığı vardır.

  • RecursionCount alanı, sahip olan iş parçacığının bu kritik bölüm için EnterCriticalSection adını kaç kez çağırdığını gösterir.

  • EntryCount alanı, sahip olan iş parçacığı dışındaki bir iş parçacığının bu kritik bölüm için EnterCriticalSection adını kaç kez çağırdığını gösterir.

Yeni başlatılan kritik bir bölüm şöyle görünür:

0:000> !critsec 433e60
CritSec mymodule!cs+0 at 00433E60
LockCount          NOT LOCKED 
RecursionCount     0
OwningThread       0
EntryCount         0
ContentionCount    0

Hata ayıklayıcı LockCount değeri olarak "KILITLI DEĞİl" değerini görüntüler. Kilidi açılmış kritik bölüm için bu alanın gerçek değeri -1'dir. Bunu dt (Görüntü Türü) komutuyla doğrulayabilirsiniz:

0:000> dt RTL_CRITICAL_SECTION 433e60
   +0x000 DebugInfo        : 0x77fcec80
   +0x004 LockCount        : -1
   +0x008 RecursionCount   : 0
   +0x00c OwningThread     : (null) 
   +0x010 LockSemaphore    : (null) 
   +0x014 SpinCount        : 0

İlk iş parçacığı EnterCriticalSection yordamını çağırdığında, kritik bölümün LockCount, RecursionCount, EntryCount ve ContentionCount alanlarının tümü birer artırılır ve OwningThread çağıranın iş parçacığı kimliği olur. EntryCount ve ContentionCount hiçbir zaman azalmaz. Örneğin:

0:000> !critsec 433e60
CritSec mymodule!cs+0 at 00433E60
LockCount          0
RecursionCount     1
OwningThread       4d0
EntryCount         0
ContentionCount    0

Bu noktada dört farklı şey olabilir.

  1. Sahip iş parçacığı EnterCriticalSection'ı yeniden çağırır. Bu, LockCount ve RecursionCount değerlerini artırır. EntryCount artırılmaz.

    0:000> !critsec 433e60
    CritSec mymodule!cs+0 at 00433E60
    LockCount          1
    RecursionCount     2
    OwningThread       4d0
    EntryCount         0
    ContentionCount    0
    
  2. Farklı bir iş parçacığı EnterCriticalSection'i çağırır. Bu, LockCount ve EntryCount değerlerini artırır. RecursionCount artırılmaz.

    0:000> !critsec 433e60
    CritSec mymodule!cs+0 at 00433E60
    LockCount          1
    RecursionCount     1
    OwningThread       4d0
    EntryCount         1
    ContentionCount    1
    
  3. Sahip iş parçacığı LeaveCriticalSection'ı çağırır. Bu, LockCount'i (-1'e düşürerek) ve RecursionCount'u (0'a düşürerek) azaltacak ve OwningThread'i 0 olarak sıfırlayacaktır.

    0:000> !critsec 433e60
    CritSec mymodule!cs+0 at 00433E60
    LockCount          NOT LOCKED 
    RecursionCount     0
    OwningThread       0
    EntryCount         0
    ContentionCount    0
    
  4. Başka bir iş parçacığı LeaveCriticalSection öğesini çağırır. Bu, LeaveCriticalSection öğesini çağıran sahip iş parçacığıyla aynı sonuçları üretir; LockCount'u -1'e ve RecursionCount'u 0'a azaltır ve OwningThread'u 0 olarak sıfırlar.

Herhangi bir iş parçacığı LeaveCriticalSection'ı çağırdığında, Windows LockCount ve RecursionCount'ı azaltır. Bu özelliğin hem iyi hem de kötü yönleri vardır. Cihaz sürücüsünün bir iş parçacığında kritik bir bölüm girmesini ve kritik bölümü başka bir iş parçacığında bırakmasını sağlar. Ancak, yanlışlıkla yanlış iş parçacığında LeaveCriticalSection çağırmayı veya LeaveCriticalSection'ı çok fazla kez çağırarak LockCount'un -1'den daha düşük değerlere ulaşmasına neden olmayı da mümkün kılar. Bu, kritik bölümü bozar ve tüm iş parçacıklarının kritik bölümde süresiz olarak beklemesine neden olur.

Windows Server 2003 SP1 ve Sonraki Sürümlerde Kritik Bölüm Alanlarını Yorumlama

Microsoft Windows Server 2003 Service Pack 1 ve windows'un sonraki sürümlerinde LockCount alanı aşağıdaki gibi ayrıştırılır:

  • En düşük bit kilit durumunu gösterir. Bu bit 0 ise kritik bölüm kilitlenir; 1 ise, kritik bölüm kilitli değildir.

  • Bir sonraki bit, bu kilit için bir iş parçacığının uyandırılıp uyandırılmadığını gösterir. Bu bit 0 ise, bu kilit için bir iş parçacığı uyandırılmıştır; 1 ise, hiçbir iş parçacığı uyandırılmamıştır.

  • Kalan bitler, kilidi bekleyen iş parçacığı sayısının bire bir tamamlayıcısıdır.

Örneğin, LockCount değerinin -22 olduğunu varsayalım. En düşük bit şu şekilde belirlenebilir:

0:009> ? 0x1 & (-0n22)
Evaluate expression: 0 = 00000000

Sonraki en düşük bit şu şekilde belirlenebilir:

0:009> ? (0x2 & (-0n22)) >> 1
Evaluate expression: 1 = 00000001

Kalan bitlerin bire bir tamamlayıcısı şu şekilde belirlenebilir:

0:009> ? ((-1) - (-0n22)) >> 2
Evaluate expression: 5 = 00000005

Bu örnekte ilk bit 0'dır ve bu nedenle kritik bölüm kilitlenir. İkinci bit 1'dir ve bu nedenle bu kilit için hiçbir iş parçacığı uyandırılmış değildir. Kalan bitlerin tamamlayıcısı 5'tir ve bu nedenle bu kilidi bekleyen beş iş parçacığı vardır.

Ek Bilgiler

Kritik bölüm zaman aşımlarında hata ayıklama hakkında bilgi için bkz. Kritik Bölüm Zaman Aşımları. Kritik bölümler hakkında genel bilgi için bkz. Microsoft Windows SDK' sı, Windows Sürücü Seti (WDK) veya Mark Russinovich ve David Solomon tarafından üretilen Microsoft Windows Internals .