Bagikan melalui


Menggunakan !analyze Extension

Langkah pertama dalam men-debug komputer atau aplikasi target yang mengalami crash adalah menggunakan perintah !analyze extension. Ekstensi ini melakukan sejumlah besar analisis otomatis. Hasil analisis ini ditampilkan di jendela Perintah Debugger.

Anda harus menggunakan opsi -v untuk tampilan data yang sepenuhnya verbose. Untuk detail tentang opsi lain, lihat halaman referensi !analyze .

Contoh User-Mode !analyze -v

Dalam contoh ini, debugger dilampirkan ke aplikasi mode pengguna yang mengalami pengecualian.

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

Debugger SolutionDb Connection::Open failed 80004005

Jika Anda terhubung ke internet, debugger mencoba mengakses database solusi crash yang dikelola oleh Microsoft. Dalam hal ini, pesan kesalahan ditampilkan, menunjukkan bahwa komputer Anda tidak dapat mengakses internet atau situs web tidak berfungsi.

FAULTING_IP: 
ntdll!PropertyLengthAsVariant+73
77f97704 cc               int     3

Bidang FAULTING_IP menunjukkan penunjuk instruksi pada saat kesalahan.

EXCEPTION_RECORD:  ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: 77f97704 (ntdll!PropertyLengthAsVariant+0x00000073)
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 3
   Parameter[0]: 00000000
   Parameter[1]: 00010101
   Parameter[2]: ffffffff

Bidang EXCEPTION_RECORD memperlihatkan rekaman pengecualian untuk crash ini. Informasi ini juga dapat dilihat dengan menggunakan perintah .exr (Rekaman Pengecualian Tampilan).

BUGCHECK_STR:  80000003

Bidang BUGCHECK_STR memperlihatkan kode pengecualian. Namanya adalah ketidakcocokan—istilah pemeriksaan bug benar-benar menandakan crash mode kernel. Dalam penelusuran kesalahan mode pengguna, kode pengecualian akan ditampilkan—dalam hal ini, 0x80000003.

DEFAULT_BUCKET_ID:  APPLICATION_FAULT

Bidang DEFAULT_BUCKET_ID menunjukkan kategori umum kegagalan yang dimiliki kegagalan ini.

PROCESS_NAME:  MyApp.exe

Bidang PROCESS_NAME menentukan nama proses yang memunculkan pengecualian.

LAST_CONTROL_TRANSFER:  from 01050963 to 77f97704

Bidang LAST_CONTROL_TRANSFER memperlihatkan panggilan terakhir pada tumpukan. Dalam hal ini, kode di alamat 0x01050963 disebut fungsi di 0x77F97704. Anda dapat menggunakan alamat ini dengan perintah ln (Daftar Simbol Terdekat) untuk menentukan modul dan fungsi tempat alamat ini berada.

STACK_TEXT:  
0006b9dc 01050963 00000000 0006ba04 000603fd ntdll!PropertyLengthAsVariant+0x73
0006b9f0 010509af 00000002 0006ba04 77e1a449 MyApp!FatalErrorBox+0x55 [D:\source_files\MyApp\util.c @ 541]
0006da04 01029f4e 01069850 0000034f 01069828 MyApp!ShowAssert+0x47 [D:\source_files\MyApp\util.c @ 579]
0006db6c 010590c3 000e01ea 0006fee4 0006feec MyApp!SelectColor+0x103 [D:\source_files\MyApp\colors.c @ 849]
0006fe04 77e11d0a 000e01ea 00000111 0000413c MyApp!MainWndProc+0x1322 [D:\source_files\MyApp\MyApp.c @ 1031]
0006fe24 77e11bc8 01057da1 000e01ea 00000111 USER32!UserCallWinProc+0x18
0006feb0 77e172b4 0006fee4 00000001 010518bf USER32!DispatchMessageWorker+0x2d0
0006febc 010518bf 0006fee4 00000000 01057c5d USER32!DispatchMessageA+0xb
0006fec8 01057c5d 0006fee4 77f82b95 77f83920 MyApp!ProcessQCQPMessage+0x3b [D:\source_files\MyApp\util.c @ 2212]
0006ff70 01062cbf 00000001 00683ed8 00682b88 MyApp!main+0x1e6 [D:\source_files\MyApp\MyApp.c @ 263]
0006ffc0 77e9ca90 77f82b95 77f83920 7ffdf000 MyApp!mainCRTStartup+0xff [D:\source_files\MyApp\crtexe.c @ 338]
0006fff0 00000000 01062bc0 00000000 000000c8 KERNEL32!BaseProcessStart+0x3d

Bidang STACK_TEXT menunjukkan jejak tumpukan komponen yang rusak.

FOLLOWUP_IP: 
MyApp!FatalErrorBox+55
01050963 5e               pop     esi

FOLLOWUP_NAME:  dbg

SYMBOL_NAME:  MyApp!FatalErrorBox+55

MODULE_NAME:  MyApp

IMAGE_NAME:  MyApp.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  383490a9

Ketika !analyze menentukan instruksi yang mungkin menyebabkan kesalahan, ia menampilkannya di bidang FOLLOWUP_IP. Bidang SYMBOL_NAME, MODULE_NAME, IMAGE_NAME, dan DEBUG_FLR_IMAGE_TIMESTAMP menunjukkan simbol, modul, nama gambar, dan tanda waktu gambar yang sesuai dengan instruksi ini.

STACK_COMMAND:  .ecxr ; kb

Bidang STACK_COMMAND memperlihatkan perintah yang digunakan untuk mendapatkan STACK_TEXT. Anda dapat menggunakan perintah ini untuk mengulangi tampilan pelacakan tumpukan ini, atau mengubahnya untuk mendapatkan informasi tumpukan terkait.

BUCKET_ID:  80000003_MyApp!FatalErrorBox+55

Bidang BUCKET_ID menunjukkan kategori kegagalan tertentu yang dimiliki kegagalan saat ini. Kategori ini membantu debugger menentukan informasi lain apa yang akan ditampilkan dalam output analisis.

Followup: dbg
---------

Untuk informasi tentang bidang FOLLOWUP_NAME dan Tindak Lanjut, lihat Bidang Tindak Lanjut dan File triage.ini.

Ada berbagai bidang lain yang mungkin muncul:

  • Jika kontrol ditransfer ke alamat yang tidak valid, maka bidang FAULTING_IP akan berisi alamat yang tidak valid ini. Alih-alih bidang FOLLOWUP_IP, bidang FAILED_INSTRUCTION_ADDRESS akan menampilkan kode yang dibongkar dari alamat ini, meskipun pembbongkaran ini mungkin tidak akan berarti. Dalam situasi ini, bidang SYMBOL_NAME, MODULE_NAME, IMAGE_NAME, dan DEBUG_FLR_IMAGE_TIMESTAMP akan merujuk ke pemanggil instruksi ini.

  • Jika prosesor salah, Anda mungkin melihat bidang SINGLE_BIT_ERROR, TWO_BIT_ERROR, atau POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Jika kerusakan memori tampaknya telah terjadi, bidang CHKIMG_EXTENSION akan menentukan perintah ekstensi !chkimg yang harus digunakan untuk menyelidiki.

Contoh Kernel-Mode !analyze -v

Dalam contoh ini, debugger dilampirkan ke komputer yang baru saja mengalami crash.

kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pagable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.

Elemen pertama tampilan menunjukkan kode pemeriksaan bug dan informasi tentang jenis pemeriksaan bug ini. Beberapa teks yang ditampilkan mungkin tidak berlaku untuk instans tertentu ini. Untuk detail selengkapnya tentang setiap pemeriksaan bug, lihat bagian Referensi Kode Pemeriksaan Bug .

Arguments:
Arg1: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: f832035c, address which referenced memory

Parameter pemeriksaan bug ditampilkan berikutnya. Mereka masing-masing diikuti oleh deskripsi. Misalnya, parameter ketiga adalah 1, dan komentar setelahnya menjelaskan bahwa ini menunjukkan bahwa operasi tulis gagal.

## Debugging Details:


WRITE_ADDRESS:  00000004 Nonpaged pool

CURRENT_IRQL:  2

Beberapa bidang berikutnya bervariasi tergantung pada sifat crash. Dalam hal ini, kita melihat bidang WRITE_ADDRESS dan CURRENT_IRQL. Ini hanya mengembalikan informasi yang ditunjukkan dalam parameter pemeriksaan bug. Dengan membandingkan pernyataan "Kumpulan tidak bertumpuk" dengan teks pemeriksaan bug yang berbunyi "upaya dilakukan untuk mengakses alamat yang dapat dipalsukan (atau benar-benar tidak valid)," kita dapat melihat bahwa alamat tidak valid. Alamat yang tidak valid dalam kasus ini 0x00000004.

FAULTING_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

Bidang FAULTING_IP menunjukkan penunjuk instruksi pada saat kesalahan.

DEFAULT_BUCKET_ID:  DRIVER_FAULT

Bidang DEFAULT_BUCKET_ID menunjukkan kategori umum kegagalan yang dimiliki kegagalan ini.

BUGCHECK_STR:  0xD1

Bidang BUGCHECK_STR menunjukkan kode pemeriksaan bug, yang telah kita lihat. Dalam beberapa kasus, informasi triase tambahan ditambahkan.

TRAP_FRAME:  f8950dfc -- (.trap fffffffff8950dfc)
.trap fffffffff8950dfc
ErrCode = 00000002
eax=81cc86dc ebx=81cc80e0 ecx=81e55688 edx=00000000 esi=81cc8028 edi=8052cf3c
eip=f832035c esp=f8950e70 ebp=f8950e90 iopl=0         nv up ei pl nz ac po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010216
USBPORT!USBPORT_BadRequestFlush+7c:
f832035c 894204           mov     [edx+0x4],eax     ds:0023:00000004=????????
.trap
Resetting default context

Bidang TRAP_FRAME menunjukkan bingkai trap untuk crash ini. Informasi ini juga dapat dilihat dengan menggunakan perintah .trap (Display Trap Frame).

LAST_CONTROL_TRANSFER:  from f83206e0 to f832035c

Bidang LAST_CONTROL_TRANSFER memperlihatkan panggilan terakhir pada tumpukan. Dalam hal ini, kode di alamat 0xF83206E0 disebut fungsi di 0xF832035C. Anda dapat menggunakan perintah ln (Daftar Simbol Terdekat) untuk menentukan modul dan fungsi alamat ini.

STACK_TEXT:  
f8950e90 f83206e0 024c7262 00000000 f8950edc USBPORT!USBPORT_BadRequestFlush+0x7c
f8950eb0 804f5561 81cc8644 81cc8028 6d9a2f30 USBPORT!USBPORT_DM_TimerDpc+0x10c
f8950fb4 804f5644 6e4be98e 00000000 ffdff000 nt!KiTimerListExpire+0xf3
f8950fe0 8052c47c 8053cf20 00000000 00002e42 nt!KiTimerExpiration+0xb0
f8950ff4 8052c16a efdefd44 00000000 00000000 nt!KiRetireDpcList+0x31

Bidang STACK_TEXT menunjukkan jejak tumpukan komponen yang rusak.

FOLLOWUP_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

Bidang FOLLOWUP_IP menunjukkan pembbongkaran instruksi yang mungkin menyebabkan kesalahan.

FOLLOWUP_NAME:  usbtri

SYMBOL_NAME:  USBPORT!USBPORT_BadRequestFlush+7c

MODULE_NAME:  USBPORT

IMAGE_NAME:  USBPORT.SYS

DEBUG_FLR_IMAGE_TIMESTAMP:  3b7d868b

Bidang SYMBOL_NAME, MODULE_NAME, IMAGE_NAME, dan DBG_FLR_IMAGE_TIMESTAMP menunjukkan tanda waktu simbol, modul, gambar, dan gambar yang sesuai dengan instruksi ini (jika valid), atau ke pemanggil instruksi ini (jika tidak).

STACK_COMMAND:  .trap fffffffff8950dfc ; kb

Bidang STACK_COMMAND memperlihatkan perintah yang digunakan untuk mendapatkan STACK_TEXT. Anda dapat menggunakan perintah ini untuk mengulangi tampilan pelacakan tumpukan ini, atau mengubahnya untuk mendapatkan informasi tumpukan terkait.

BUCKET_ID:  0xD1_W_USBPORT!USBPORT_BadRequestFlush+7c

Bidang BUCKET_ID menunjukkan kategori kegagalan tertentu yang dimiliki kegagalan saat ini. Kategori ini membantu debugger menentukan informasi lain apa yang akan ditampilkan dalam output analisis.

Untuk informasi tentang bidang FOLLOWUP_NAME dan Tindak Lanjut, lihat Bidang Tindak Lanjut dan File triage.ini.

Ada berbagai bidang lain yang mungkin muncul:

  • Jika kontrol ditransfer ke alamat yang tidak valid, maka bidang FAULTING_IP akan berisi alamat yang tidak valid ini. Alih-alih bidang FOLLOWUP_IP, bidang FAILED_INSTRUCTION_ADDRESS akan menampilkan kode yang dibongkar dari alamat ini, meskipun pembbongkaran ini mungkin tidak akan berarti. Dalam situasi ini, bidang SYMBOL_NAME, MODULE_NAME, IMAGE_NAME, dan DBG_FLR_IMAGE_TIMESTAMP akan merujuk ke pemanggil instruksi ini.

  • Jika prosesor salah, Anda mungkin melihat bidang SINGLE_BIT_ERROR, TWO_BIT_ERROR, atau POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Jika kerusakan memori tampaknya telah terjadi, bidang CHKIMG_EXTENSION akan menentukan perintah ekstensi !chkimg yang harus digunakan untuk menyelidiki.

  • Jika pemeriksaan bug terjadi dalam kode driver perangkat, namanya dapat ditampilkan di bidang BUGCHECKING_DRIVER.

Bidang Tindak Lanjut dan File triage.ini

Dalam mode pengguna dan mode kernel, bidang Tindak Lanjut dalam tampilan akan menampilkan informasi tentang pemilik bingkai tumpukan saat ini, jika ini dapat ditentukan. Informasi ini ditentukan dengan cara berikut:

  1. Ketika ekstensi !analyze digunakan, debugger dimulai dengan bingkai atas di tumpukan dan menentukan apakah itu bertanggung jawab atas kesalahan. Jika tidak, bingkai berikutnya dianalisis. Proses ini berlanjut sampai bingkai yang mungkin salah ditemukan.

  2. Debugger mencoba menentukan pemilik modul dan fungsi dalam bingkai ini. Jika pemilik dapat ditentukan, bingkai ini dianggap salah.

  3. Jika pemilik tidak dapat ditentukan, debugger meneruskan ke bingkai tumpukan berikutnya, dan seterusnya, sampai pemilik ditentukan (atau tumpukan benar-benar diperiksa). Bingkai pertama yang pemiliknya ditemukan dalam pencarian ini dianggap salah. Jika tumpukan habis tanpa ada informasi yang ditemukan, tidak ada bidang Tindak Lanjut yang ditampilkan.

  4. Pemilik bingkai yang salah ditampilkan di bidang Tindak Lanjut. Jika !analyze -v digunakan, bidang FOLLOWUP_IP, SYMBOL_NAME, MODULE_NAME, IMAGE_NAME, dan DBG_FLR_IMAGE_TIMESTAMP akan merujuk ke bingkai ini.

Agar bidang Tindak Lanjut menampilkan informasi yang berguna, Anda harus terlebih dahulu membuat file triage.ini yang berisi nama modul dan pemilik fungsi.

File triage.ini harus mengidentifikasi pemilik semua modul yang mungkin memiliki kesalahan. Anda dapat menggunakan string informasi alih-alih pemilik aktual, tetapi string ini tidak boleh berisi spasi. Jika Anda yakin bahwa modul tidak akan rusak, Anda dapat menghilangkan modul ini atau menunjukkan bahwa modul tersebut harus dilewati. Dimungkinkan juga untuk menentukan pemilik fungsi individu, memberikan proses triase granularitas yang lebih halus.

Untuk detail tentang sintaks file triage.ini, lihat Menentukan Pemilik Modul dan Fungsi.

Teknik !analyze tambahan

Jika tidak ada crash atau pengecualian yang terjadi, !analyze akan menampilkan teks yang sangat singkat yang memberikan status target saat ini. Dalam situasi tertentu, Anda mungkin ingin memaksa analisis berlangsung seolah-olah terjadi crash. Gunakan !analyze -f untuk menyelesaikan tugas ini.

Dalam mode pengguna, jika pengecualian telah terjadi tetapi Anda yakin masalah yang mendasar adalah utas yang digantung, atur utas saat ini ke utas yang Anda selidiki, lalu gunakan !analyze -hang. Ekstensi ini akan melakukan analisis tumpukan utas untuk menentukan apakah ada utas yang memblokir utas lain.

Dalam mode kernel, jika pemeriksaan bug telah terjadi tetapi Anda yakin masalah yang mendasar adalah utas yang digantung, gunakan !analyze -hang. Ekstensi ini akan menyelidiki kunci yang disimpan oleh sistem dan memindai rantai antrean DPC, dan akan menampilkan indikasi utas yang digantung. Jika Anda yakin masalahnya adalah kebuntuan sumber daya mode kernel, gunakan ekstensi !deadlock bersama dengan opsi Deteksi Kebuntuan Driver Verifier.

Anda juga dapat secara otomatis mengabaikan masalah yang diketahui. Untuk melakukan ini, Anda harus terlebih dahulu membuat file XML yang berisi daftar masalah yang diketahui yang diformat. Gunakan ekstensi !analyze -c -loadKnownIssuesFile untuk memuat file ini. Kemudian ketika pengecualian atau jeda terjadi, gunakan ekstensi !analyze -c . Jika pengecualian cocok dengan salah satu masalah yang diketahui, target akan melanjutkan eksekusi. Jika target tidak melanjutkan eksekusi, maka Anda dapat menggunakan !analyze -v untuk menentukan penyebab masalah.

Lihat juga

Lihat topik ini untuk informasi tambahan.

!Menganalisis

Referensi Bug Check Code

Analisis crash dump menggunakan debugger Windows (WinDbg)

Menganalisis File Cadangan Kernel-Mode dengan WinDbg