Dela via


Analys av kraschdumpar

Alla buggar kan inte hittas före lanseringen, vilket innebär att inte alla buggar som genererar undantag kan hittas före lanseringen. Lyckligtvis har Microsoft i Platform SDK inkluderat en funktion som hjälper utvecklare att samla in information om undantag som upptäcks av användare. Funktionen MiniDumpWriteDump skriver nödvändig kraschdumpinformation till en fil utan att spara hela processutrymmet. Den här kraschdumpinformationsfilen kallas för en minidump. Den här tekniska artikeln innehåller information om hur du skriver och använder en minidump.

Skriva en minidump

De grundläggande alternativen för att skriva en minidump är följande:

  • Gör ingenting. Windows genererar automatiskt en minidump när ett program genererar ett ohanterat undantag. Automatisk generering av en minidump är tillgänglig sedan Windows XP. Om användaren tillåter det skickas minidumpen till Microsoft och inte till utvecklaren via Windows Error Reporting (WER). Utvecklare kan få åtkomst till dessa minidumps via Windows Desktop Application Program.

    Användning av WER kräver:

    • Utvecklare signerar sina program med Hjälp av Authenticode
    • Program har en giltig VERSIONINFO-resurs i varje körbar fil och DLL

    Om du implementerar en anpassad rutin för ohanterade undantag uppmanas du starkt att använda funktionen ReportFault i undantagshanteraren för att även skicka en automatiserad minidump till WER. Funktionen ReportFault hanterar alla problem med att ansluta till och skicka minidämparen till WER. Att inte skicka minidumps till WER strider mot kraven i Spel för Windows.

    Mer information om WER finns i Windows-felrapportering.

  • Använd en produkt från Microsoft Visual Studio Team System. På menyn Felsökning klickar du på Spara dump som för att spara en kopia av en dump. Användning av en lokalt sparad dump är bara ett alternativ för intern testning och felsökning.

  • Lägg till kod i projektet. Lägg till funktionen MiniDumpWriteDump och lämplig kod för undantagshantering för att spara och skicka en minidump direkt till utvecklaren. Den här artikeln visar hur du implementerar det här alternativet. Observera dock att MiniDumpWriteDump för närvarande inte fungerar med hanterad kod och endast är tillgänglig i Windows XP, Windows Vista, Windows 7.

Trådsäkerhet

MiniDumpWriteDump ingår i DBGHELP-biblioteket. Det här biblioteket är inte trådsäkert, så alla program som använder MiniDumpWriteDump bör synkronisera alla trådar innan de försöker anropa MiniDumpWriteDump.

Skriva en minidump med kod

Den faktiska implementeringen är enkel. Följande är ett enkelt exempel på hur du använder 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()))
    {
    }
}

Det här exemplet visar den grundläggande användningen av MiniDumpWriteDump och den minsta information som krävs för att anropa den. Namnet på dumpfilen är upp till utvecklaren. För att undvika kollisioner med filnamn rekommenderar vi dock att du genererar filnamnet från programmets namn och versionsnummer, process- och tråd-ID:t samt datum och tid. Detta hjälper också till att hålla minidumparna grupperade efter program och version. Det är upp till utvecklaren att bestämma hur mycket information som ska användas för att särskilja minidupliceringsfilnamn.

Det bör noteras att sökvägsnamnet i föregående exempel genererades genom att anropa funktionen GetTempPath för att hämta sökvägen till katalogen som är avsedd för temporära filer. Användningen av den här katalogen fungerar även med användarkonton med minst privilegier och förhindrar även att minidämparen tar upp hårddiskutrymme när den inte längre behövs.

Om du arkiverar produkten under den dagliga byggprocessen måste du även inkludera symboler för versionen så att du kan felsöka en gammal version av produkten om det behövs. Du måste också vidta åtgärder för att upprätthålla fullständiga kompilatoroptimeringar samtidigt som du genererar symboler. Detta kan göras genom att öppna projektets egenskaper i utvecklingsmiljön och, för versionskonfigurationen, göra följande:

  1. Till vänster på projektets egenskapssida klickar du på C/C++. Som standard visas inställningarna för Allmänt. Till höger på projektets egenskapssida anger du Felsökningsinformationsformat till Program Database (/Zi).
  2. Till vänster på egenskapssidan expanderar du Linkeroch klickar sedan på Felsökning. Till höger på egenskapssidan anger du Generera felsökningsinformation till Ja (/FELSÖKNING).
  3. Klicka på Optimizationoch ange References to Eliminate Unreferenced Data (/OPT:REF).
  4. Ange Aktivera COMDAT-vikning för att Ta bort redundanta COMDAT(/OPT:ICF).

Mer information finns i MINIDUMP_EXCEPTION_INFORMATION struktur och funktionen MiniDumpWriteDump.

Använda Dumpchk.exe

Dumpchk.exe är ett kommandoradsverktyg som kan användas för att verifiera att en dumpfil har skapats korrekt. Om Dumpchk.exe genererar ett fel är dumpfilen skadad och kan inte analyseras. Information om hur du använder Dumpchk.exefinns i Använda Dumpchk.exe för att kontrollera en minnesdumpfil.

Dumpchk.exe ingår i Windows XP-produkt-CD:n och kan installeras på System Drive\Program Files\Support Tools\ by running Setup.exe i mappen Support\Tools\ på Windows XP-produkt-CD:n. Du kan också hämta den senaste versionen av Dumpchk.exe genom att ladda ned och installera felsökningsverktygen som är tillgängliga från Windows FelsökningsverktygWindows Hardware Developer Central.

Analysera en minidump

Det är lika enkelt att öppna en minidump för analys som att skapa en.

Analysera en

  1. Öppna Visual Studio.
  2. På menyn Arkiv klickar du på Öppna project.
  3. Ange Filer av typen till Dump Files, navigera till dumpfilen, markera den och klicka på Öppna.
  4. Kör felsökningsprogrammet.

Felsökningsprogrammet skapar en simulerad process. Den simulerade processen stoppas med den instruktion som orsakade kraschen.

Använda Microsofts offentliga symbolserver

För att hämta stacken för krascher på drivrutins- eller systemnivå kan det vara nödvändigt att konfigurera Visual Studio så att det pekar på Microsofts offentliga symbolserver.

Ange en sökväg till Microsoft-symbolservern

  1. På menyn Felsökning klickar du på Alternativ.
  2. I dialogrutan Alternativ öppnar du noden Felsökning och klickar på symboler.
  3. Kontrollera att Sök endast på ovanstående platser när symboler läses in manuellt inte är markerat, såvida du inte vill läsa in symboler manuellt när du felsöker.
  4. Om du använder symboler på en fjärrsymbolserver kan du förbättra prestanda genom att ange en lokal katalog som symboler kan kopieras till. Det gör du genom att ange en sökväg för Cache-symboler från symbolservern till den här katalogen. Om du vill ansluta till Microsofts offentliga symbolserver måste du aktivera den här inställningen. Observera att om du felsöker ett program på en fjärrdator refererar cachekatalogen till en katalog på fjärrdatorn.
  5. Klicka på OK.
  6. Eftersom du använder Microsofts offentliga symbolserver visas dialogrutan Licensavtal för slutanvändare. Klicka på Ja för att godkänna avtalet och ladda ned symboler till din lokala cache.

Felsöka en minidump med WinDbg

Du kan också använda WinDbg, ett felsökningsprogram som ingår i Windows Felsökningsverktyg, för att felsöka en minidämpare. Med WinDbg kan du felsöka utan att behöva använda Visual Studio. Information om hur du laddar ned Windows Felsökningsverktyg finns i Windows FelsökningsverktygWindows Hardware Developer Central.

När du har installerat Windows Felsökningsverktyg måste du ange symbolsökvägen i WinDbg.

Ange en symbolsökväg i WinDbg

  1. På menyn Arkiv klickar du på symbolsökväg.

  2. I fönstret sökväg för symbolsökning anger du följande:

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

Använda Copy-Protection-verktyg med minidupliceringar

Utvecklare måste också vara medvetna om hur deras kopieringsskyddsschema kan påverka minidämparen. De flesta kopieringsskyddsscheman har egna descramble-verktyg, och det är upp till utvecklaren att lära sig att använda dessa verktyg med MiniDumpWriteDump.

Sammanfattning

Funktionen MiniDumpWriteDump kan vara ett mycket användbart verktyg för att samla in och lösa buggar efter att produkten har släppts. Genom att skriva en anpassad undantagshanterare som använder MiniDumpWriteDump kan utvecklaren anpassa informationssamlingen och förbättra felsökningsprocessen. Funktionen är tillräckligt flexibel för att användas i alla C++-baserade projekt och bör betraktas som en del av alla projekts stabilitetsprocess.