Analisi del dump di arresto anomalo

Non tutti i bug possono essere trovati prima della versione, il che significa che non tutti i bug che generano eccezioni possono essere trovati prima della versione. Fortunatamente, Microsoft ha incluso in Platform SDK una funzione per aiutare gli sviluppatori a raccogliere informazioni sulle eccezioni individuate dagli utenti. La funzione MiniDumpWriteDump scrive le informazioni di dump di arresto anomalo necessarie in un file senza salvare l'intero spazio del processo. Questo file di informazioni sul dump di arresto anomalo viene chiamato minidump. Questo articolo tecnico fornisce informazioni su come scrivere e usare un minidump.

Scrittura di un minidump

Le opzioni di base per la scrittura di un minidump sono le seguenti:

  • Non eseguire alcuna operazione. Windows genera automaticamente un minidump ogni volta che un programma genera un'eccezione non gestita. La generazione automatica di un minidump è disponibile dal momento che Windows XP. Se l'utente lo consente, il minidump verrà inviato a Microsoft e non allo sviluppatore, tramite Segnalazione errori Windows (Segnalazione errori Windows). Gli sviluppatori possono accedere a questi minidump tramite il programma applicazione desktop di Windows.

    L'uso di Segnalazione errori Windows richiede:

    • Sviluppatori per firmare le applicazioni usando Authenticode
    • Le applicazioni hanno una risorsa VERSIONINFO valida in ogni eseguibile e DLL

    Se si implementa una routine personalizzata per le eccezioni non gestite, si consiglia vivamente di usare la funzione ReportFault nel gestore eccezioni per inviare anche un minidump automatizzato a Segnalazione errori Windows. La funzione ReportFault gestisce tutti i problemi di connessione a e l'invio del minidump alla Segnalazione errori Windows. L'invio di minidump a Segnalazione errori Windows viola i requisiti dei giochi per Windows.

    Per altre informazioni sul funzionamento di Segnalazione errori Windows, vedere How Segnalazione errori Windows Works.For more information on how Segnalazione errori Windows works, see How Segnalazione errori Windows Works. Per una spiegazione dei dettagli della registrazione, vedere Introduzione Segnalazione errori Windows nella zona ISV di MSDN.

  • Usare un prodotto dal Microsoft Visual Studio Team System. Nel menu Debug fare clic su Salva dump come per salvare una copia di un dump. L'uso di un dump salvato in locale è solo un'opzione per i test interni e il debug.

  • Aggiungere codice al progetto. Aggiungere la funzione MiniDumpWriteDump e il codice di gestione delle eccezioni appropriato per salvare e inviare un minidump direttamente allo sviluppatore. Questo articolo illustra come implementare questa opzione. Si noti tuttavia che MiniDumpWriteDump attualmente non funziona con il codice gestito ed è disponibile solo in Windows XP, Windows Vista, Windows 7.

Thread safety

MiniDumpWriteDump fa parte della libreria DBGHELP. Questa libreria non è thread-safe, quindi qualsiasi programma che usa MiniDumpWriteDump deve sincronizzare tutti i thread prima di tentare di chiamare MiniDumpWriteDump.

Scrittura di un minidump con codice

L'implementazione effettiva è semplice. Di seguito è riportato un semplice esempio di come usare MiniDumpWriteDump.

#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>

int GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
    BOOL bMiniDumpSuccessful;
    WCHAR szPath[MAX_PATH]; 
    WCHAR szFileName[MAX_PATH]; 
    WCHAR* szAppName = L"AppName";
    WCHAR* szVersion = L"v1.0";
    DWORD dwBufferSize = MAX_PATH;
    HANDLE hDumpFile;
    SYSTEMTIME stLocalTime;
    MINIDUMP_EXCEPTION_INFORMATION ExpParam;

    GetLocalTime( &stLocalTime );
    GetTempPath( dwBufferSize, szPath );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s", szPath, szAppName );
    CreateDirectory( szFileName, NULL );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", 
               szPath, szAppName, szVersion, 
               stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, 
               stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, 
               GetCurrentProcessId(), GetCurrentThreadId());
    hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, 
                FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

    ExpParam.ThreadId = GetCurrentThreadId();
    ExpParam.ExceptionPointers = pExceptionPointers;
    ExpParam.ClientPointers = TRUE;

    bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
                    hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);

    return EXCEPTION_EXECUTE_HANDLER;
}


void SomeFunction()
{
    __try
    {
        int *pBadPtr = NULL;
        *pBadPtr = 0;
    }
    __except(GenerateDump(GetExceptionInformation()))
    {
    }
}

In questo esempio viene illustrato l'utilizzo di base di MiniDumpWriteDump e le informazioni minime necessarie per chiamarla. Il nome del file dump è fino allo sviluppatore; Tuttavia, per evitare collisioni tra nomi file, è consigliabile generare il nome del file dal nome e dal numero di versione dell'applicazione, dall'ID di elaborazione e thread e dalla data e dall'ora. Ciò aiuterà anche a mantenere i minidump raggruppati in base all'applicazione e alla versione. Lo sviluppatore decide la quantità di informazioni usate per distinguere i nomi di file minidump.

Si noti che il nome del percorso nell'esempio precedente è stato generato chiamando la funzione GetTempPath per recuperare il percorso della directory designata per i file temporanei. L'uso di questa directory funziona anche con account utente con privilegi minimi e impedisce anche al minidump di occupare spazio su disco rigido dopo che non è più necessario.

Se si archivia il prodotto durante il processo di compilazione giornaliero, assicurarsi anche di includere simboli per la compilazione in modo che sia possibile eseguire il debug di una versione precedente del prodotto, se necessario. È anche necessario eseguire passaggi per mantenere le ottimizzazioni complete del compilatore durante la generazione di simboli. Questa operazione può essere eseguita aprendo le proprietà del progetto nell'ambiente di sviluppo e, per la configurazione della versione, eseguire le operazioni seguenti:

  1. Sul lato sinistro della pagina delle proprietà del progetto fare clic su C/C++. Per impostazione predefinita, vengono visualizzate le impostazioni generali . Sul lato destro della pagina delle proprietà del progetto impostare Debug Information Formatto Program Database (/Zi).
  2. Sul lato sinistro della pagina della proprietà espandere Linker e quindi fare clic su Debug. Sul lato destro della pagina delle proprietà impostare Genera informazioni di debug su Sì (/DEBUG).
  3. Fare clic su Ottimizzazione e impostare Riferimenti a Eliminate Dati non referenziati (/OPT:REF).
  4. Impostare Abilita la riduzione COMDAT per rimuovere le COMDAT ridondanti (/OPT:ICF).

MSDN ha informazioni più dettagliate sulla struttura MINIDUMP_EXCEPTION_INFORMATION e sulla funzione MiniDumpWriteDump .

Uso di Dumpchk.exe

Dumpchk.exe è un'utilità della riga di comando che può essere usata per verificare che sia stato creato correttamente un file dump. Se Dumpchk.exe genera un errore, il file dump è danneggiato e non può essere analizzato. Per informazioni sull'uso di Dumpchk.exe, vedere Come usare Dumpchk.exe per controllare un file di dump della memoria.

Dumpchk.exe è incluso nel CD del prodotto XP Windows e può essere installato in System Drive\Programmi\Strumenti di supporto\ eseguendo Setup.exe nella cartella Support\Tools\ nel CD del prodotto WINDOWS XP. È anche possibile ottenere la versione più recente di Dumpchk.exe scaricando e installando gli strumenti di debug disponibili da Windows Debug Tools in Windows Hardware Developer Central.

Analisi di un minidump

L'apertura di un minidump per l'analisi è facile da creare.

Per analizzare un minidump

  1. Aprire Visual Studio.
  2. Nel menu File fare clic su Apri Project.
  3. Impostare File di tipodump, passare al file di dump, selezionarlo e fare clic su Apri.
  4. Eseguire il debugger.

Il debugger creerà un processo simulato. Il processo simulato verrà arrestato all'istruzione che ha causato l'arresto anomalo.

Uso del server di simboli pubblici Microsoft

Per ottenere lo stack per gli arresti anomali a livello di driver o di sistema, potrebbe essere necessario configurare Visual Studio per puntare al server dei simboli pubblici Microsoft.

Per impostare un percorso sul server di simboli Microsoft

  1. Nel menu Debug fare clic su Opzioni.
  2. Nella finestra di dialogo Opzioni aprire il nodo Debug e fare clic su Simboli.
  3. Assicurarsi di cercare le posizioni precedenti solo quando i simboli vengono caricati manualmente non è selezionato, a meno che non si desideri caricare manualmente i simboli quando si esegue il debug.
  4. Se si usano simboli in un server di simboli remoti, è possibile migliorare le prestazioni specificando una directory locale in cui è possibile copiare i simboli. A tale scopo, immettere un percorso per i simboli della cache dal server dei simboli a questa directory. Per connettersi al server dei simboli pubblici Microsoft, è necessario abilitare questa impostazione. Si noti che se si esegue il debug di un programma in un computer remoto, la directory della cache fa riferimento a una directory nel computer remoto.
  5. Fare clic su OK.
  6. Poiché si usa il server di simboli pubblici Microsoft, viene visualizzata una finestra di dialogo Contratto di licenza utente finale. Fare clic su per accettare il contratto e scaricare i simboli nella cache locale.

Debug di un minidump con WinDbg

È anche possibile usare WinDbg, un debugger che fa parte degli strumenti di debug di Windows, per eseguire il debug di un minidump. WinDbg consente di eseguire il debug senza dover usare Visual Studio. Per scaricare strumenti di debug Windows, vedere strumenti di debug Windows in Windows Hardware Developer Central.

Dopo aver installato Windows Debug Tools, è necessario immettere il percorso del simbolo in WinDbg.

Per immettere un percorso del simbolo in WinDbg

  1. Nel menu File fare clic su Percorso simbolo.

  2. Nella finestra Percorso ricerca simboli immettere quanto segue:

    "srv\*c:\\cache\*https://msdl.microsoft.com/download/symbols;"

Uso di strumenti di Copy-Protection con Minidumps

Gli sviluppatori devono anche essere consapevoli del modo in cui lo schema di protezione delle copie potrebbe influire sul minidump. La maggior parte degli schemi di protezione delle copie dispone di strumenti di descramble e spetta allo sviluppatore imparare a usare questi strumenti con MiniDumpWriteDump.

Riepilogo

La funzione MiniDumpWriteDump può essere uno strumento estremamente utile per raccogliere e risolvere i bug dopo il rilascio del prodotto. La scrittura di un gestore eccezioni personalizzato che usa MiniDumpWriteDump consente allo sviluppatore di personalizzare la raccolta di informazioni e migliorare il processo di debug. La funzione è sufficientemente flessibile da essere usata in qualsiasi progetto basato su C++e deve essere considerata parte del processo di stabilità di qualsiasi progetto.