Absturzabbildanalyse

Nicht alle Fehler können vor der Veröffentlichung gefunden werden, was bedeutet, dass nicht alle Fehler, die Ausnahmen auslösen, vor der Veröffentlichung gefunden werden können. Glücklicherweise hat Microsoft eine Funktion in das Platform SDK integriert, mit der Entwickler Informationen zu Ausnahmen sammeln können, die von Benutzern erkannt werden. Die MiniDumpWriteDump-Funktion schreibt die erforderlichen Absturzabbildinformationen in eine Datei, ohne den gesamten Prozessspeicherplatz zu speichern. Diese Absturzabbild-Informationsdatei wird als Minidump bezeichnet. Dieser technische Artikel enthält Informationen zum Schreiben und Verwenden eines Minidumps.

Schreiben eines Minidumps

Die grundlegenden Optionen zum Schreiben eines Minidumps sind wie folgt:

  • Sie unternehmen nichts. Windows generiert automatisch einen Minidump, wenn ein Programm eine nicht behandelte Ausnahme auslöst. Die automatische Generierung eines Minidumps ist seit Windows XP verfügbar. Wenn der Benutzer dies zulässt, wird der Minidump über Windows-Fehlerberichterstattung (WER) an Microsoft und nicht an den Entwickler gesendet. Entwickler können über das Windows-Desktopanwendungsprogramm auf diese Minidumps zugreifen.

    Die Verwendung von WER erfordert:

    • Entwickler, um ihre Anwendungen mit Authenticode zu signieren
    • Anwendungen verfügen in jeder ausführbaren Datei und DLL über eine gültige VERSIONINFO-Ressource.

    Wenn Sie eine benutzerdefinierte Routine für nicht behandelte Ausnahmen implementieren, werden Sie dringend aufgefordert, die ReportFault-Funktion im Ausnahmehandler zu verwenden, um auch einen automatisierten Minidump an WER zu senden. Die ReportFault-Funktion behandelt alle Probleme beim Herstellen einer Verbindung mit und senden des Minidumps an WER. Das Senden von Minidumps an WER verstößt gegen die Anforderungen von Games für Windows.

    Weitere Informationen zur Funktionsweise von WER finden Sie unter Funktionsweise Windows-Fehlerberichterstattung. Eine Erläuterung der Registrierungsdetails finden Sie unter Introducing Windows-Fehlerberichterstattung onMSDN's ISV Zone.

  • Verwenden Sie ein Produkt aus Microsoft Visual Studio Team System. Klicken Sie im Menü Debuggen auf Speicherabbild speichern unter, um eine Kopie eines Speicherabbilds zu speichern. Die Verwendung eines lokal gespeicherten Speicherabbilds ist nur eine Option zum internen Testen und Debuggen.

  • Fügen Sie Ihrem Projekt Code hinzu. Fügen Sie die MiniDumpWriteDump-Funktion und den entsprechenden Ausnahmebehandlungscode hinzu, um einen Minidump zu speichern und direkt an den Entwickler zu senden. In diesem Artikel wird veranschaulicht, wie Sie diese Option implementieren. Beachten Sie jedoch, dass MiniDumpWriteDump derzeit nicht mit verwaltetem Code funktioniert und nur unter Windows XP, Windows Vista und Windows 7 verfügbar ist.

Threadsicherheit

MiniDumpWriteDump ist Teil der DBGHELP-Bibliothek. Diese Bibliothek ist nicht threadsicher. Daher sollte jedes Programm, das MiniDumpWriteDump verwendet, alle Threads vor dem Versuch, MiniDumpWriteDump aufzurufen, synchronisieren.

Schreiben eines Minidumps mit Code

Die tatsächliche Implementierung ist einfach. Im Folgenden finden Sie ein einfaches Beispiel für die Verwendung von 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 diesem Beispiel wird die grundlegende Verwendung von MiniDumpWriteDump und die minimalen Informationen veranschaulicht, die für den Aufruf erforderlich sind. Der Name der Speicherabbilddatei liegt beim Entwickler. Um Dateinamenkonflikte zu vermeiden, empfiehlt es sich jedoch, den Dateinamen aus dem Namen und der Versionsnummer der Anwendung, den Prozess- und Thread-IDs sowie dem Datum und der Uhrzeit zu generieren. Dies trägt auch dazu bei, die Minidumps nach Anwendung und Version gruppiert zu halten. Es liegt beim Entwickler, zu entscheiden, wie viele Informationen zur Unterscheidung von Minidump-Dateinamen verwendet werden.

Beachten Sie, dass der Pfadname im vorherigen Beispiel durch Aufrufen der GetTempPath-Funktion generiert wurde, um den Pfad des Verzeichnisses abzurufen, das für temporäre Dateien festgelegt ist. Die Verwendung dieses Verzeichnisses funktioniert auch bei Benutzerkonten mit den geringsten Rechten und verhindert auch, dass der Minidump Festplattenspeicher belegt, nachdem er nicht mehr benötigt wird.

Wenn Sie das Produkt während des täglichen Buildprozesses archivieren, müssen Sie auch Symbole für den Build einfügen, damit Sie bei Bedarf eine alte Version des Produkts debuggen können. Sie müssen auch Schritte unternehmen, um vollständige Compileroptimierungen beim Generieren von Symbolen beizubehalten. Dazu können Sie die Eigenschaften Ihres Projekts in der Entwicklungsumgebung öffnen und für die Releasekonfiguration die folgenden Schritte ausführen:

  1. Klicken Sie links auf der Eigenschaftenseite des Projekts auf C/C++. Standardmäßig werden allgemeine Einstellungen angezeigt. Legen Sie rechts auf der Eigenschaftenseite des Projekts Debuginformationsformat auf Programmdatenbank (/Zi) fest.
  2. Erweitern Sie links auf der Eigenschaftenseite linker, und klicken Sie dann auf Debuggen. Legen Sie rechts auf der Eigenschaftenseite Debuginformationen generieren auf Ja (/DEBUG) fest.
  3. Klicken Sie auf Optimierung, und legen Sie Verweise auf E fest, dienicht referenzierten Daten (/OPT:REF).
  4. Legen Sie COMDAT-Faltung aktivieren fest, um redundante COMDATs (/OPT:ICF) zu entfernen.

MSDN enthält ausführlichere Informationen zur MINIDUMP_EXCEPTION_INFORMATION-Struktur und zur MiniDumpWriteDump-Funktion .

Verwenden von Dumpchk.exe

Dumpchk.exe ist ein Befehlszeilenprogramm, mit dem überprüft werden kann, ob eine Speicherabbilddatei ordnungsgemäß erstellt wurde. Wenn Dumpchk.exe einen Fehler generiert, ist die Speicherabbilddatei beschädigt und kann nicht analysiert werden. Informationen zur Verwendung von Dumpchk.exe finden Sie unter How to Use Dumpchk.exe to Check a Memory Dump File (Verwenden von Dumpchk.exe zum Überprüfen einer Speicherabbilddatei).

Dumpchk.exe ist auf der Windows XP-Produkt-CD enthalten und kann auf Systemlaufwerk\Programme\Supporttools\ installiert werden, indem sie Setup.exe im Ordner Support\Tools\ auf der Windows XP-Produkt-CD ausführen. Sie können auch die neueste Version von Dumpchk.exe erhalten, indem Sie die Debugtools herunterladen und installieren, die unter Windows Debugging Tools in Windows Hardware Developer Central verfügbar sind.

Analysieren eines Minidumps

Das Öffnen eines Minidumps für die Analyse ist so einfach wie das Erstellen eines Minidumps.

So analysieren Sie einen Minidump

  1. Öffnen Sie Visual Studio.
  2. Klicken Sie im Menü Datei auf Projekt öffnen.
  3. Legen Sie Dateien vom Typ auf DumpDateien fest, navigieren Sie zur Speicherabbilddatei, wählen Sie sie aus, und klicken Sie auf Öffnen.
  4. Führen Sie den Debugger aus.

Der Debugger erstellt einen simulierten Prozess. Der simulierte Prozess wird an der Anweisung angehalten, die den Absturz verursacht hat.

Verwenden des Öffentlichen Symbolservers von Microsoft

Um den Stapel für Abstürze auf Treiber- oder Systemebene abzurufen, muss Visual Studio möglicherweise so konfiguriert werden, dass es auf den öffentlichen Microsoft-Symbolserver verweist.

So legen Sie einen Pfad zum Microsoft-Symbolserver fest

  1. Klicken Sie im Menü Debuggen auf Optionen.
  2. Öffnen Sie im Dialogfeld Optionen den Knoten Debuggen , und klicken Sie auf Symbole.
  3. Stellen Sie sicher, dass Die oben genannten Speicherorte nur suchen, wenn Symbole manuell geladen werden , nicht ausgewählt ist, es sei denn, Sie möchten Symbole beim Debuggen manuell laden.
  4. Wenn Sie Symbole auf einem Remotesymbolserver verwenden, können Sie die Leistung verbessern, indem Sie ein lokales Verzeichnis angeben, in das Symbole kopiert werden können. Geben Sie dazu einen Pfad für Cachesymbole vom Symbolserver zu diesem Verzeichnis ein. Um eine Verbindung mit dem öffentlichen Microsoft-Symbolserver herzustellen, müssen Sie diese Einstellung aktivieren. Wenn Sie ein Programm auf einem Remotecomputer debuggen, bezieht sich das Cacheverzeichnis auf ein Verzeichnis auf dem Remotecomputer.
  5. Klicken Sie auf OK.
  6. Da Sie den öffentlichen Microsoft-Symbolserver verwenden, wird ein Dialogfeld endbenutzerlizenzvertrag angezeigt. Klicken Sie auf Ja , um die Vereinbarung zu akzeptieren und Symbole in Ihren lokalen Cache herunterzuladen.

Debuggen eines Minidumps mit WinDbg

Sie können auch WinDbg verwenden, einen Debugger, der Teil der Windows-Debugtools ist, um ein Minidump zu debuggen. Mit WinDbg können Sie debuggen, ohne Visual Studio verwenden zu müssen. Informationen zum Herunterladen der Windows-Debugtools finden Sie unter Windows Debugging Tools in Windows Hardware Developer Central.

Nach der Installation der Windows-Debugtools müssen Sie den Symbolpfad in WinDbg eingeben.

So geben Sie einen Symbolpfad in WinDbg ein

  1. Klicken Sie im Menü Datei auf Symbolpfad.

  2. Geben Sie im Fenster Symbolsuchepfad Folgendes ein:

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

Verwenden von Copy-Protection Tools mit Minidumps

Entwickler müssen auch wissen, wie sich ihr Kopierschutzschema auf den Minidump auswirken kann. Die meisten Kopierschutzschemas verfügen über eigene Decramble-Tools, und es liegt an den Entwicklern, zu erfahren, wie Sie diese Tools mit MiniDumpWriteDump verwenden.

Zusammenfassung

Die MiniDumpWriteDump-Funktion kann ein äußerst nützliches Tool zum Sammeln und Beheben von Fehlern sein, nachdem das Produkt veröffentlicht wurde. Das Schreiben eines benutzerdefinierten Ausnahmehandlers, der MiniDumpWriteDump verwendet, ermöglicht es dem Entwickler, die Informationssammlung anzupassen und den Debugprozess zu verbessern. Die Funktion ist flexibel genug, um in jedem C++-basierten Projekt verwendet zu werden und sollte als Teil des Stabilitätsprozesses jedes Projekts betrachtet werden.