Bagikan melalui


Menulis Plugin Ekstensi Analisis untuk Memperluas !analyze

Anda dapat memperluas kemampuan perintah !analyze debugger dengan menulis plugin ekstensi analisis. Dengan menyediakan plugin ekstensi analisis, Anda dapat berpartisipasi dalam analisis pemeriksaan bug atau pengecualian dengan cara yang khusus untuk komponen atau aplikasi Anda sendiri.

Ketika Anda menulis plugin ekstensi analisis, Anda juga menulis file metadata yang menjelaskan situasi di mana Anda ingin plugin Anda dipanggil. Ketika !analyze berjalan, ia menemukan, memuat, dan menjalankan plugin ekstensi analisis yang sesuai.

Untuk menulis plugin ekstensi analisis dan membuatnya tersedia untuk !analyze, ikuti langkah-langkah ini.

  • Buat DLL yang mengekspor fungsi _EFN_Analyze .
  • Buat file metadata yang memiliki nama yang sama dengan DLL Anda dan ekstensi .alz. Misalnya, jika DLL Anda diberi nama MyAnalyzer.dll, file metadata Anda harus diberi nama MyAnalyzer.alz. Untuk informasi tentang cara membuat file metadata, lihat File Metadata untuk Ekstensi Analisis. Tempatkan file metadata di direktori yang sama dengan DLL Anda.
  • Di debugger, gunakan perintah .extpath untuk menambahkan direktori Anda ke jalur file ekstensi. Misalnya, jika FILE DLL dan metadata Anda berada di folder bernama c:\MyAnalyzer, masukkan perintah .extpath+ c:\MyAnalyzer.

Ketika perintah !analyze berjalan di debugger, mesin analisis melihat jalur file ekstensi untuk file metadata yang memiliki ekstensi .alz. Mesin analisis membaca file metadata untuk menentukan plugin ekstensi analisis mana yang harus dimuat. Misalnya, mesin analisis berjalan sebagai respons terhadap 0xA IRQL_NOT_LESS_OR_EQUAL Pemeriksaan Bug, dan membaca file metadata bernama MyAnalyzer.alz yang berisi entri berikut.

PluginId       MyPlugin
DebuggeeClass  Kernel
BugCheckCode   0xA
BugCheckCode   0xE2

Entri BugCheckCode 0x0A menentukan bahwa plugin ini ingin berpartisipasi dalam analisis 0xA Pemeriksaan Bug, sehingga mesin analisis memuat MyAnalyzer.dll (yang harus berada dalam direktori yang sama dengan MyAnalyzer.alz) dan memanggil fungsi _EFN_Analyze-nya .

Catatan Baris terakhir file metadata harus diakhir dengan karakter baris baru.

Contoh Kerangka

Berikut adalah contoh kerangka yang dapat Anda gunakan sebagai titik awal.

  1. Buat DLL bernama MyAnalyzer.dll yang mengekspor fungsi _EFN_Analyze yang ditampilkan di sini.

    #include <windows.h>
    #define KDEXT_64BIT
    #include <wdbgexts.h>
    #include <dbgeng.h>
    #include <extsfns.h>
    
    extern "C" __declspec(dllexport) HRESULT _EFN_Analyze(_In_ PDEBUG_CLIENT4 Client, 
       _In_ FA_EXTENSION_PLUGIN_PHASE CallPhase, _In_ PDEBUG_FAILURE_ANALYSIS2 pAnalysis)
    { 
       HRESULT hr = E_FAIL;
    
       PDEBUG_CONTROL pControl = NULL;
       hr = Client->QueryInterface(__uuidof(IDebugControl), (void**)&pControl);
    
       if(S_OK == hr && NULL != pControl)
       {
          IDebugFAEntryTags* pTags = NULL;
          pAnalysis->GetDebugFATagControl(&pTags);
    
          if(NULL != pTags)
          {
             if(FA_PLUGIN_INITILIZATION == CallPhase)
             { 
                pControl->Output(DEBUG_OUTPUT_NORMAL, "My analyzer: initialization\n");  
             }
             else if(FA_PLUGIN_STACK_ANALYSIS == CallPhase)
             {
                pControl->Output(DEBUG_OUTPUT_NORMAL, "My analyzer: stack analysis\n"); 
             }
             else if(FA_PLUGIN_PRE_BUCKETING == CallPhase)
             {
                pControl->Output(DEBUG_OUTPUT_NORMAL, "My analyzer: prebucketing\n");
             }
             else if(FA_PLUGIN_POST_BUCKETING == CallPhase)
             {
                pControl->Output(DEBUG_OUTPUT_NORMAL, "My analyzer: post bucketing\n");    
                FA_ENTRY_TYPE entryType = pTags->GetType(DEBUG_FLR_BUGCHECK_CODE);       
                pControl->Output(DEBUG_OUTPUT_NORMAL, "The data type for the DEBUG_FLR_BUGCHECK_CODE tag is 0x%x.\n\n", entryType);
             }
          }
    
          pControl->Release();
       }
       return hr;
    }
    
  2. Buat file metadata bernama MyAnalyzer.alz yang memiliki entri berikut.

    PluginId      MyPlugin
    DebuggeeClass Kernel
    BugCheckCode  0xE2
    

    Catatan Baris terakhir file metadata harus diakhir dengan karakter baris baru.

  3. Buat sesi debugging mode kernel antara host dan komputer target.

  4. Di komputer host, letakkan MyAnalyzer.dll dan MyAnalyzer.alz di folder c:\MyAnalyzer.

  5. Di komputer host, di debugger, masukkan perintah ini.

    .extpath+ c:\MyAnalyzer

    .Kecelakaan

  6. Perintah .crash menghasilkan 0xE2 MANUALLY_INITIATED_CRASH Pemeriksaan Bug pada komputer target, yang menyebabkan jeda ke debugger pada komputer host. Mesin analisis pemeriksaan bug (berjalan di debugger di komputer host) membaca MyAnalyzer.alz dan melihat bahwa MyAnalyzer.dll dapat berpartisipasi dalam menganalisis pemeriksaan bug 0xE2. Jadi mesin analisis memuat MyAnalyzer.dll dan memanggil fungsi _EFN_Analyze .

    Verifikasi bahwa Anda melihat output yang mirip dengan yang berikut ini di debugger.

    *                        Bugcheck Analysis                                    *
    *                                                                             *
    *******************************************************************************
    
    Use !analyze -v to get detailed debugging information.
    
    BugCheck E2, {0, 0, 0, 0}
    
    My analyzer: initialization
    My analyzer: stack analysis
    My analyzer: prebucketing
    My analyzer: post bucketing
    The data type for the DEBUG_FLR_BUGCHECK_CODE tag is 0x1.
    

Output debugger sebelumnya menunjukkan bahwa mesin analisis yang disebut fungsi _EFN_Analyze empat kali: sekali untuk setiap fase analisis. Mesin analisis melewati fungsi _EFN_Analyze dua penunjuk antarmuka. Klien adalah antarmuka IDebugClient4 , dan pAnalysis adalah antarmuka IDebugFailureAnalysis2 . Kode dalam contoh kerangka sebelumnya menunjukkan cara mendapatkan dua penunjuk antarmuka lagi. Client->QueryInterface mendapatkan antarmuka IDebugControl , dan pAnalysis->GetDebugFATagControl mendapatkan antarmuka IDebugFAEntryTags .

Entri Analisis Kegagalan, Tag, dan Jenis Data

Mesin analisis membuat objek DebugFailureAnalysis untuk mengatur data yang terkait dengan kegagalan kode tertentu. Objek DebugFailureAnalysis memiliki kumpulan entri analisis kegagalan (entri FA), yang masing-masing diwakili oleh struktur FA_ENTRY . Plugin ekstensi analisis menggunakan antarmuka IDebugFailureAnalysis2 untuk mendapatkan akses ke koleksi entri FA ini. Setiap entri FA memiliki tag yang mengidentifikasi jenis informasi yang dikandung entri. Misalnya, entri FA mungkin memiliki tag DEBUG_FLR_BUGCHECK_CODE, yang memberi tahu kami bahwa entri berisi kode pemeriksaan bug. Tag adalah nilai dalam enumerasi DEBUG_FLR_PARAM_TYPE (ditentukan dalam extsfns.h), yang juga disebut enumerasi FA_TAG .

typedef enum _DEBUG_FLR_PARAM_TYPE {
    ...
    DEBUG_FLR_BUGCHECK_CODE,
    ...
    DEBUG_FLR_BUILD_VERSION_STRING,
    ...
} DEBUG_FLR_PARAM_TYPE;

typedef DEBUG_FLR_PARAM_TYPE FA_TAG;

Sebagian besar entri FA memiliki blok data terkait. Anggota DataSize dari struktur FA_ENTRY memegang ukuran blok data. Beberapa entri FA tidak memiliki blok data terkait; semua informasi disampaikan oleh tag . Dalam kasus tersebut, anggota DataSize memiliki nilai 0.

typedef struct _FA_ENTRY
{
    FA_TAG Tag;
    USHORT FullSize;
    USHORT DataSize;
} FA_ENTRY, *PFA_ENTRY;

Setiap tag memiliki sekumpulan properti: misalnya, nama, deskripsi, dan jenis data. Objek DebugFailureAnalysis dikaitkan dengan objek DebugFailureAnalysisTags , yang berisi kumpulan properti tag. Diagram berikut mengilustrasikan asosiasi ini.

Diagram memperlihatkan mesin analisis, objek DebugFailureAnalysis, dan objek DebugFailureAnalysisTags.

Objek DebugFailureAnalysis memiliki kumpulan entri FA yang termasuk dalam sesi analisis tertentu. Objek DebugFailureAnalysisTags terkait memiliki kumpulan properti tag yang hanya menyertakan tag yang digunakan oleh sesi analisis yang sama. Seperti yang ditunjukkan oleh diagram sebelumnya, mesin analisis memiliki tabel tag global yang menyimpan informasi terbatas tentang sekumpulan tag besar yang umumnya tersedia untuk digunakan oleh sesi analisis.

Biasanya sebagian besar tag yang digunakan oleh sesi analisis adalah tag standar; artinya, tag adalah nilai dalam enumerasi FA_TAG . Namun, plug-in ekstensi analisis dapat membuat tag kustom. Plug-in ekstensi analisis dapat menambahkan entri FA ke objek DebugFailureAnalysis dan menentukan tag kustom untuk entri tersebut. Dalam hal ini, properti untuk tag kustom ditambahkan ke kumpulan properti tag di objek DebugFailureAnalysisTags terkait.

Anda dapat mengakses DebugFailureAnalysisTags melalui antarmuka tag IDebugFAEntry. Untuk mendapatkan penunjuk ke antarmuka IDebugFAEntry, panggil metode GetDebugFATagControl antarmuka IDebugFailureAnalysis2 .

Setiap tag memiliki properti jenis data yang dapat Anda periksa untuk menentukan jenis data dalam entri analisis kegagalan. Jenis data diwakili oleh nilai dalam enumerasi FA_ENTRY_TYPE .

Baris kode berikut mendapatkan jenis data tag DEBUG_FLR_BUILD_VERSION_STRING . Dalam hal ini, jenis data DEBUG_FA_ENTRY_ANSI_STRING. Dalam kode, pAnalysis adalah penunjuk ke antarmuka IDebugFailureAnalysis2 .

IDebugFAEntryTags* pTags = pAnalysis->GetDebugFATagControl(&pTags);

if(NULL != pTags)
{
   FA_ENTRY_TYPE entryType = pTags->GetType(DEBUG_FLR_BUILD_VERSION_STRING);
}

Jika entri analisis kegagalan tidak memiliki blok data, jenis data tag terkait DEBUG_FA_ENTRY_NO_TYPE.

Ingat bahwa objek DebugFailureAnalysis memiliki kumpulan entri FA. Untuk memeriksa semua entri FA dalam koleksi, gunakan metode NextEntry . Contoh berikut menunjukkan cara melakukan iterasi melalui seluruh koleksi entri FA. Asumsikan bahwa pAnalysis adalah penunjuk ke antarmuka IDebugFailureAnalysis2. Perhatikan bahwa kita mendapatkan entri pertama dengan meneruskan NULL ke NextEntry.

PFA_ENTRY entry = pAnalysis->NextEntry(NULL);

while(NULL != entry)
{
   // Do something with the entry

   entry = pAnalysis->NextEntry(entry);
}

Tag dapat memiliki nama dan deskripsi. Dalam kode berikut, pAnalysis adalah penunjuk ke antarmuka IDebugFailureAnalysis , pControl adalah penunjuk ke antarmuka IDebugControl , dan pTags merupakan penunjuk ke antarmuka IDebugFAEntryTags . Kode menunjukkan cara menggunakan metode GetProperties untuk mendapatkan nama dan deskripsi tag yang terkait dengan entri FA.

#define MAX_NAME_LENGTH 64
#define MAX_DESCRIPTION_LENGTH 512

CHAR name[MAX_NAME_LENGTH] = {0};
ULONG nameSize = MAX_NAME_LENGTH;
CHAR desc[MAX_DESCRIPTION_LENGTH] = {0};
ULONG descSize = MAX_DESCRIPTION_LENGTH;
                  
PFA_ENTRY pEntry = pAnalysis->NextEntry(NULL); 
pTags->GetProperties(pEntry->Tag, name, &nameSize, desc, &descSize, NULL);
pControl->Output(DEBUG_OUTPUT_NORMAL, "The name is %s\n", name);
pControl->Output(DEBUG_OUTPUT_NORMAL, "The description is %s\n", desc);

Lihat juga

Menulis Ekstensi Debugger Analisis Kustom

_EFN_Analyze

File Metadata untuk Plug-in Ekstensi Analisis

IDebugFailureAnalysis2

IDebugFAEntryTags