Bagikan melalui


Mendapatkan Pemberitahuan

Kode berikut menunjukkan cara mendapatkan dan melaporkan informasi status yang terperinci dari penangan simbol, mengenai pencarian dan pemuatan modul serta file simbol yang sesuai.

Banyak yang terbiasa dengan debugger WinDbg mungkin mengingat perintah yang disebut "!sym noisy". Perintah ini digunakan oleh pengguna untuk menentukan apakah WinDbg dapat atau tidak memuat berkas simbol. Ini menunjukkan daftar terperinci tentang semua yang dicoba oleh handler simbol.

Daftar yang sama ini juga tersedia untuk siapa saja yang mengembangkan klien untuk pengelola simbol DbgHelp.

Pertama, panggil SymSetOptions dengan SYMOPT_DEBUG. Hal ini menyebabkan DbgHelp mengaktifkan pemberitahuan debug.

Setelah memanggil SymInitialize, gunakan SymRegisterCallback64 untuk mendaftarkan fungsi panggilan balik yang akan dipanggil DbgHelp setiap kali peristiwa menarik terjadi. Dalam contoh ini, fungsi panggilan balik disebut SymRegisterCallbackProc64. Fungsi panggilan balik simbol diteruskan berbagai kode tindakan yang dapat mereka tangani sesuai dengan jenis. Dalam contoh ini, kami hanya menangani kode tindakan CBA_EVENT. Fungsi ini meneruskan string yang berisi informasi verbose tentang peristiwa yang terjadi dalam proses pemuatan simbol. Kejadian ini bisa mencakup apa saja, mulai dari upaya untuk membaca data dalam berkas eksekusi hingga berhasil menemukan file simbol. SymRegisterCallbackProc64 menampilkan string tersebut dan mengembalikan TRUE.

Penting

Pastikan Anda mengembalikan FALSE ke setiap kode tindakan yang tidak Anda tangani, jika tidak, Anda mungkin mengalami perilaku yang tidak terdefinisi. Lihat SymRegisterCallbackProc64 untuk daftar semua kode tindakan dan implikasinya.

 

Sekarang setelah panggilan balik terdaftar, saatnya untuk memuat modul yang ditentukan pada baris perintah dengan memanggil SymLoadModuleEx.

Terakhir, hubungi SymCleanup sebelum keluar.

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#ifdef UNICODE
 #define DBGHELP_TRANSLATE_TCHAR
#endif
#include <dbghelp.h>

// Here is an implementation of a Symbol Callback function.

BOOL 
CALLBACK 
SymRegisterCallbackProc64(
    __in HANDLE hProcess,
    __in ULONG ActionCode,
    __in_opt ULONG64 CallbackData,
    __in_opt ULONG64 UserContext
    )
{
    UNREFERENCED_PARAMETER(hProcess);
    UNREFERENCED_PARAMETER(UserContext);
    
    PIMAGEHLP_CBA_EVENT evt;

    // If SYMOPT_DEBUG is set, then the symbol handler will pass
    // verbose information on its attempt to load symbols.
    // This information be delivered as text strings.
    
    switch (ActionCode)
    {
    case CBA_EVENT:
        evt = (PIMAGEHLP_CBA_EVENT)CallbackData;
        _tprintf(_T("%s"), (PTSTR)evt->desc);
        break;

    // CBA_DEBUG_INFO is the old ActionCode for symbol spew.
    // It still works, but we use CBA_EVENT in this example.
#if 0
    case CBA_DEBUG_INFO:
        _tprintf(_T("%s"), (PTSTR)CallbackData);
        break;
#endif

    default:
        // Return false to any ActionCode we don't handle
        // or we could generate some undesirable behavior.
        return FALSE;
    }

    return TRUE;
}

// Main code.

int __cdecl
#ifdef UNICODE
_tmain(
#else
main(
#endif
    __in int argc,
    __in_ecount(argc) PCTSTR argv[]
    )
{
    BOOL status;
    int rc = -1;
    HANDLE hProcess;
    DWORD64 module;
    
    if (argc < 2)
    {
        _tprintf(_T("You must specify an executable image to load.\n"));
        return rc;
    }

    // If we want to se debug spew, we need to set this option.
        
    SymSetOptions(SYMOPT_DEBUG);
    
    // We are not debugging an actual process, so lets use a placeholder
    // value of 1 for hProcess just to ID these calls from any other
    // series we may want to load.  For this simple case, anything will do.
    
    hProcess = (HANDLE)1;
    
    // Initialize the symbol handler.  No symbol path.  
    // Just let dbghelp use _NT_SYMBOL_PATH
    
    status = SymInitialize(hProcess, NULL, false);
    if (!status)
    {
        _tprintf(_T("Error 0x%x calling SymInitialize.\n"), GetLastError());
        return rc;
    }
     
    // Now register our callback.
    
    status = SymRegisterCallback64(hProcess, SymRegisterCallbackProc64, NULL);
    if (!status)
    {
        _tprintf(_T("Error 0x%x calling SymRegisterCallback64.\n"), GetLastError());
        goto cleanup;
    }
    
    // Go ahead and load a module for testing.
    
    module = SymLoadModuleEx(hProcess,  // our unique id
                             NULL,      // no open file handle to image
                             argv[1],   // name of image to load
                             NULL,      // no module name - dbghelp will get it
                             0,         // no base address - dbghelp will get it
                             0,         // no module size - dbghelp will get it
                             NULL,      // no special MODLOAD_DATA structure
                             0);        // flags
    if (!module)
    {
        _tprintf(_T("Error 0x%x calling SymLoadModuleEx.\n"), GetLastError());
        goto cleanup;
    }
    rc = 0;
    
cleanup:
    SymCleanup(hProcess);
    
    return rc;    
}

Menentukan NULL sebagai parameter kedua dari SymInitialize menunjukkan bahwa penangan simbol seharusnya menggunakan jalur pencarian default untuk menemukan file simbol. Untuk informasi terperinci tentang bagaimana penangan simbol menemukan file simbol atau bagaimana aplikasi dapat menentukan jalur pencarian simbol, lihat Jalur Simbol.

Menjalankan program ini menunjukkan bagaimana jalur simbol diproses. Saat DbgHelp melihat melalui jalur simbol untuk menemukan file simbol, ia berulang kali memanggil SymRegisterCallbackProc64 yang, pada gilirannya, menampilkan string berikut yang diteruskan oleh DbgHelp.

d:\load.exe c:\home\dbghelp.dll
DBGHELP: No header for c:\home\dbghelp.dll.  Searching for image on disk
DBGHELP: c:\home\dbghelp.dll - OK
DBGHELP: .\dbghelp.pdb - file not found
DBGHELP: .\dll\dbghelp.pdb - file not found
DBGHELP: .\symbols\dll\dbghelp.pdb - file not found
DBGHELP: .\symbols\dll\dbghelp.pdb - file not found
DBGHELP: cache*c:\symbols\dbghelp.pdb - file not found
DBGHELP: cache*c:\symbols\dll\dbghelp.pdb - file not found
DBGHELP: cache*c:\symbols\symbols\dll\dbghelp.pdb - file not found
DBGHELP: d:\nt.binaries.amd64chk\symbols.pri\dbg\dbghelp.pdb - file not found
DBGHELP: dbghelp - private symbols & lines
         dbghelp.pdb