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. Berikut adalah 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

Menafsirkan 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 telah memanggil 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 telah memanggil EnterCriticalSection untuk section kritis ini.

  • Bidang EntryCount menunjukkan berapa kali utas selain utas pemilik memanggil EnterCriticalSection untuk bagian kritis 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 dalam section kritis semuanya bertambah satu, dan OwningThread menjadi ID utas dari pemanggil. EntryCount dan ContentionCount tidak pernah diderementasi. 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. Thread yang memiliki memanggil EnterCriticalSection lagi. Ini akan menaikkan LockCount dan RecursionCount. EntryCount tidak dinaikkan.

    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 bertambah.

    0:000> !critsec 433e60
    CritSec mymodule!cs+0 at 00433E60
    LockCount          1
    RecursionCount     1
    OwningThread       4d0
    EntryCount         1
    ContentionCount    1
    
  3. Thread 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 alur pemilik yang memanggil LeaveCriticalSection -- itu akan mengurangi LockCount (ke -1) dan RecursionCount (ke 0), dan akan mengatur ulang OwningThread ke 0.

Ketika setiap 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 di utas lain. Namun, itu juga memungkinkan untuk secara tidak sengaja memanggil LeaveCriticalSection pada utas yang salah, atau memanggil LeaveCriticalSection terlalu banyak kali dan menyebabkan LockCount mencapai nilai yang lebih rendah dari -1. Ini merusak bagian penting dan menyebabkan semua utas menunggu tanpa batas waktu di bagian kritis.

Menafsirkan Bidang Bagian Penting 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 penting dikunci; jika 1, bagian penting tidak dikunci.

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

  • Bit yang tersisa adalah komplemen satu dari jumlah utas yang menunggu untuk mendapatkan 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

Komplemen satu dari bit 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 penting dikunci. Bit kedua adalah 1, jadi tidak ada utas yang dibangunkan untuk kunci ini. Pelengkap dari bit yang tersisa adalah 5, oleh karena itu, ada lima utas yang menunggu kunci ini.

Informasi Tambahan

Untuk informasi tentang cara melakukan debugging batas waktu bagian kritis, 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.