Bagikan melalui


Menampilkan Bagian Penting

Bagian penting dapat ditampilkan dalam mode pengguna dengan berbagai metode yang berbeda. Arti pasti dari setiap bidang bergantung pada versi Microsoft Windows yang Anda gunakan.

Menampilkan Bagian Penting

Bagian penting dapat ditampilkan oleh ekstensi !ntsdexts.locks, ekstensi !critsec, ekstensi !cs, dan perintah dt (Jenis Tampilan).

Ekstensi !ntsdexts.locks menampilkan daftar bagian penting yang terkait dengan proses saat ini. Jika opsi -v digunakan, semua bagian penting ditampilkan. Ini contohnya:

0:000> !locks

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

....
Scanned 37 critical sections

Jika Anda mengetahui alamat bagian penting yang ingin Anda tampilkan, Anda dapat menggunakan ekstensi !critsec . Ini menampilkan kumpulan informasi yang sama dengan !ntsdexts.locks. Contohnya:

0:000> !critsec 77fc49e0

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

Ekstensi !cs dapat menampilkan bagian penting berdasarkan alamatnya, mencari rentang alamat untuk bagian penting, dan bahkan menampilkan jejak tumpukan yang terkait dengan setiap bagian penting. Beberapa fitur ini memerlukan simbol Windows penuh agar berfungsi dengan baik. Jika Pemverifikasi Aplikasi aktif, !cs -t dapat digunakan untuk menampilkan pohon bagian penting. Lihat halaman referensi !cs untuk detail dan contoh.

Informasi yang ditampilkan oleh !cs sedikit berbeda dari yang ditunjukkan oleh !ntsdexts.locks dan !critsec. Contohnya:

## 0:000> !cs 77fc49e0

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

Perintah dt (Jenis Tampilan) dapat digunakan untuk menampilkan konten harfiah struktur RTL_CRITICAL_SECTION. Contohnya:

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

Menginterpretasikan Bidang Bagian Penting di Windows XP dan Windows 2000

Bidang terpenting dari struktur bagian penting adalah sebagai berikut:

  • Di Microsoft Windows 2000, dan Windows XP, bidang LockCount menunjukkan berapa kali utas apa pun disebut rutinitas EnterCriticalSection untuk bagian penting ini, dikurangi satu. Bidang ini dimulai pada -1 untuk bagian penting yang tidak terkunci. Setiap panggilan EnterCriticalSection menaikkan nilai ini; setiap panggilan LeaveCriticalSection menguranginya. Misalnya, jika LockCount adalah 5, bagian penting ini dikunci, satu utas telah memperolehnya, dan lima utas tambahan menunggu kunci ini.

  • Bidang RecursionCount menunjukkan berapa kali utas pemilik disebut EnterCriticalSection untuk bagian penting ini.

  • Bidang EntryCount menunjukkan berapa kali utas selain utas pemilik disebut EnterCriticalSection untuk bagian penting ini.

Bagian penting yang baru diinisialisasi terlihat seperti ini:

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

Debugger menampilkan "NOT LOCKED" sebagai nilai untuk LockCount. Nilai aktual bidang ini untuk bagian penting yang tidak terkunci adalah -1. Anda dapat memverifikasi ini dengan perintah dt (Jenis Tampilan):

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

Ketika utas pertama memanggil rutinitas EnterCriticalSection , bidang LockCount, RecursionCount, EntryCount , dan ContentionCount bagian penting semuanya bertambah satu, dan OwningThread menjadi ID utas pemanggil. EntryCount dan ContentionCount tidak pernah direkrementasi. Contohnya:

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

Pada titik ini, empat hal berbeda dapat terjadi.

  1. Utas pemilik memanggil EnterCriticalSection lagi. Ini akan menaikkan LockCount dan RecursionCount. EntryCount tidak ditingkatkan.

    0:000> !critsec 433e60
    CritSec mymodule!cs+0 at 00433E60
    LockCount          1
    RecursionCount     2
    OwningThread       4d0
    EntryCount         0
    ContentionCount    0
    
  2. Utas yang berbeda memanggil EnterCriticalSection. Ini akan menaikkan LockCount dan EntryCount. RecursionCount tidak ditingkatkan.

    0:000> !critsec 433e60
    CritSec mymodule!cs+0 at 00433E60
    LockCount          1
    RecursionCount     1
    OwningThread       4d0
    EntryCount         1
    ContentionCount    1
    
  3. Utas pemilik memanggil LeaveCriticalSection. Ini akan mengurangi LockCount (ke -1) dan RecursionCount (ke 0), dan akan mengatur ulang OwningThread ke 0.

    0:000> !critsec 433e60
    CritSec mymodule!cs+0 at 00433E60
    LockCount          NOT LOCKED 
    RecursionCount     0
    OwningThread       0
    EntryCount         0
    ContentionCount    0
    
  4. Utas lain memanggil LeaveCriticalSection. Ini menghasilkan hasil yang sama dengan utas pemilik yang memanggil LeaveCriticalSection -- itu akan menurunkan LockCount (ke -1) dan RecursionCount (ke 0), dan akan mengatur ulang OwningThread ke 0.

Ketika utas memanggil LeaveCriticalSection, Windows mengurangi LockCount dan RecursionCount. Fitur ini memiliki aspek yang baik dan buruk. Ini memungkinkan driver perangkat untuk memasuki bagian penting pada satu utas dan meninggalkan bagian penting pada utas lain. Namun, memungkinkan juga untuk secara tidak sengaja memanggil LeaveCriticalSection pada utas yang salah, atau memanggil LeaveCriticalSection terlalu sering dan menyebabkan LockCount mencapai nilai yang lebih rendah dari -1. Ini merusak bagian penting dan menyebabkan semua utas menunggu tanpa batas waktu pada bagian kritis.

Menginterpretasikan Bidang Bagian Kritis di Windows Server 2003 SP1 dan Yang Lebih Baru

Di Microsoft Windows Server 2003 Service Pack 1 dan versi Windows yang lebih baru, bidang LockCount diurai sebagai berikut:

  • Bit terendah menunjukkan status kunci. Jika bit ini adalah 0, bagian kritis dikunci; jika 1, bagian kritis tidak dikunci.

  • Bit berikutnya menunjukkan apakah utas telah dibangunkan untuk kunci ini. Jika bit ini adalah 0, maka utas telah dibangunkan untuk kunci ini; jika 1, tidak ada utas yang telah dibangunkan.

  • Bit yang tersisa adalah pelengkap satu-satunya dari jumlah utas yang menunggu kunci.

Sebagai contoh, misalkan LockCount adalah -22. Bit terendah dapat ditentukan dengan cara ini:

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

Bit terendah berikutnya dapat ditentukan dengan cara ini:

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

Pelengkap yang tersisa dapat ditentukan dengan cara ini:

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

Dalam contoh ini, bit pertama adalah 0 dan oleh karena itu bagian kritis dikunci. Bit kedua adalah 1, jadi tidak ada utas yang dibangunkan untuk kunci ini. Pelengkap bit yang tersisa adalah 5, sehingga ada lima utas yang menunggu kunci ini.

Informasi Tambahan

Untuk informasi tentang cara men-debug batas waktu bagian penting, lihat Batas Waktu Bagian Penting. Untuk informasi umum tentang bagian penting, lihat Microsoft Windows SDK, Windows Driver Kit (WDK), atau Microsoft Windows Internals oleh Mark Russinovich dan David Solomon.