Abilitazione del debug postmortem

Gestione delle eccezioni in modalità utente

Eccezioni e punti di interruzione

Gli errori più comuni dell'applicazione sono denominati eccezioni. Tra cui violazioni di accesso, errori di divisione per zero, overflow numerici, eccezioni CLR e molti altri tipi di errori. Le applicazioni possono anche causare interruzioni del punto di interruzione. Questi si verificano quando Windows non è in grado di eseguire l'applicazione (ad esempio, quando non è possibile caricare un modulo necessario) o quando viene rilevato un punto di interruzione. I punti di interruzione possono essere inseriti nel codice da un debugger o richiamati tramite una funzione come DebugBreak.

Precedenza dei gestori di eccezioni

In base ai valori di configurazione e ai debugger attivi, Windows gestisce gli errori in modalità utente in diversi modi. La sequenza seguente mostra la precedenza usata per la gestione degli errori in modalità utente:

  1. Se un debugger in modalità utente è attualmente collegato al processo di errore, tutti gli errori causeranno l'interruzione della destinazione in questo debugger.

    Se il debugger in modalità utente è collegato, non verranno usati altri metodi di gestione degli errori, anche se viene usato il comando gn (Go with Exception Not Handled).

  2. Se non è collegato alcun debugger in modalità utente e il codice in esecuzione dispone di routine di gestione delle eccezioni specifiche (ad esempio, try - except), questa routine di gestione delle eccezioni tenterà di gestire l'errore.

  3. Se non è collegato alcun debugger in modalità utente e Windows dispone di una connessione di debug del kernel aperta e l'errore è un interrupt del punto di interruzione, Windows tenterà di contattare il debugger del kernel.

    Le connessioni di debug del kernel devono essere aperte durante il processo di avvio di Windows. Se si desidera impedire che un interrupt in modalità utente si interrompa nel debugger del kernel, è possibile usare l'utilità KDbgCtrl con il parametro -du . Per informazioni dettagliate su come configurare le connessioni di debug del kernel e su come usare KDbgCtrl, vedere Getting Set Up for Debugging (Come configurare per il debug).

    Nel debugger del kernel è possibile usare gh (Go With Exception Handled) per ignorare l'errore e continuare a eseguire la destinazione. È possibile usare gn (Go With Exception Not Handled) per ignorare il debugger del kernel e andare al passaggio 4.

  4. Se le condizioni nei passaggi 1, 2 e 3 non si applicano, Windows attiverà uno strumento di debug configurato nei valori del Registro di sistema AeDebug. Qualsiasi programma può essere selezionato in anticipo come strumento da usare in questa situazione. Il programma scelto viene definito debugger postmortem.

  5. Se le condizioni nei passaggi 1, 2 e 3 non si applicano e non è registrato alcun debugger postmortem, Segnalazione errori Windows (WER) visualizza un messaggio e fornisce soluzioni, se disponibili. WeR scrive anche un file di dump della memoria se i valori appropriati vengono impostati nel Registro di sistema. Per altre informazioni, vedere Uso di WER e raccolta di dump in modalità utente.

Funzione DebugBreak

Se è stato installato un debugger postmortem, è possibile interrompere deliberatamente il debugger da un'applicazione in modalità utente chiamando la funzione DebugBreak .

Specifica di un debugger Postmortem

Questa sezione descrive come configurare strumenti come WinDbg come debugger postmortem. Dopo la configurazione, il debugger postmortem verrà avviato automaticamente ogni volta che un'applicazione si arresta in modo anomalo.

Chiavi del Registro di sistema post Mortem Debugger

Segnalazione errori Windows (WER) crea il processo del debugger postmortem usando i valori impostati nella chiave del Registro di sistema AeDebug.

HkLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug

Esistono due valori principali del Registro di sistema di interesse, Debugger e Auto. Il valore del Registro di sistema debugger specifica la riga di comando per il debugger postmortem. Il valore del Registro di sistema automatico specifica se il debugger postmortem viene avviato automaticamente o se viene visualizzata prima una finestra di messaggio di conferma.

Debugger (REG_SZ)

Questo valore REG_SZ specifica il debugger che gestirà il debug postmortem.

Il percorso completo del debugger deve essere elencato a meno che il debugger non si trovi in una directory che si trova nel percorso predefinito.

La riga di comando viene generata dalla stringa Debugger tramite una chiamata di stile printf che include 3 parametri. Anche se l'ordine è fisso, non è necessario usare alcun parametro o tutti i parametri disponibili.

DWORD (%ld): ID processo del processo di destinazione.

DWORD (%ld): handle di eventi duplicato nel processo del debugger postmortem. Se il debugger postmortem segnala l'evento, wer continuerà il processo di destinazione senza attendere il termine del debugger postmortem. L'evento deve essere segnalato solo se il problema è stato risolto. Se il debugger postmortem termina senza segnalare l'evento, wer continua la raccolta di informazioni sui processi di destinazione.

void* (%p): indirizzo di una struttura JIT_DEBUG_INFO allocata nello spazio indirizzi del processo di destinazione. La struttura contiene informazioni aggiuntive sull'eccezione e contesto.

Auto (REG_SZ) Questo valore REG_SZ è sempre 0 o 1.

Se Auto è impostato su 0, viene visualizzata una finestra di messaggio di conferma prima dell'avvio del processo di debug postmortem.

Se Auto è impostato su 1, il debugger postmortem viene creato immediatamente.

Quando modifichi manualmente il Registro di sistema, esegui questa operazione con molta attenzione, perché le modifiche non necessarie al Registro di sistema potrebbero non consentire l'avvio di Windows.

Esempio di utilizzo della riga di comando

Molti debugger postmortem usano una riga di comando che include le opzioni -p e -e per indicare che i parametri sono rispettivamente PID ed Event. Ad esempio, l'installazione di WinDbg tramite windbg.exe -I crea i valori seguenti:

Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1

È possibile usare i parametri WER %ld %ld %p in modo flessibile. Ad esempio, non è necessario specificare alcuna opzione o tra i parametri WER. Ad esempio, l'installazione di Windows Sysinternals ProcDump tramite procdump.exe -i crea i valori seguenti senza commutatori tra i parametri WER %ld %ld %p:

Debugger = "<Path>\procdump.exe" -accepteula -j "c:\Dumps" %ld %ld %p
Auto = 1

Debugger a 32 e 64 bit

In una piattaforma a 64 bit, i valori del Registro di sistema Debugger (REG_SZ) e Auto (REG_SZ) vengono definiti singolarmente per le applicazioni a 64 bit e a 32 bit. Per archiviare i valori di debug post mortem dell'applicazione a 32 bit, viene usata una chiave di Windows in Windows (WOW).

HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug

In una piattaforma a 64 bit usare un debugger post-mortem a 32 bit per i processi a 32 bit e un debugger a 64 bit per i processi a 64 bit. In questo modo si evita un debugger a 64 bit incentrato sui thread WOW64, anziché sui thread a 32 bit, in un processo a 32 bit.

Per molti debugger postmortem, inclusi gli strumenti di debug per i debugger postmortem di Windows, ciò comporta l'esecuzione del comando di installazione due volte; una volta con la versione x86 e una volta con la versione x64. Ad esempio, per usare WinDbg come debugger postmortem interattivo, il windbg.exe -I comando viene eseguito due volte, una per ogni versione.

Installazione a 64 bit:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I

In questo modo viene aggiornata la chiave del Registro di sistema con questi valori.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -p %ld -e %ld –g

Installazione a 32 bit:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I

In questo modo viene aggiornata la chiave del Registro di sistema con questi valori.

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe" -p %ld -e %ld –g

Configurazione dei debugger Post Mortem

Strumenti di debug per Windows

Gli strumenti di debug per i debugger di Windows supportano tutti l'impostazione come debugger postmortem. Il comando di installazione prevede che il processo venga sottoposto a debug in modo interattivo.

WinDbg

Per impostare il debugger postmortem su WinDbg, eseguire windbg -I. Deve I essere in maiuscolo. Questo comando visualizzerà un messaggio di esito positivo o negativo dopo l'uso. Per usare applicazioni a 32 e a 64 bit, eseguire il comando per i debugger 64 e 32.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe –I
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\windbg.exe –I

Questa è la modalità di configurazione della voce del Registro di sistema AeDebug quando windbg -I viene eseguita.

Debugger = "<Path>\WinDbg -p %ld -e %ld -g"
Auto = 1

Negli esempi Path <> è la directory in cui si trova il debugger.

I parametri -p e -e passano l'ID processo e l'evento, come illustrato in precedenza.

- g passa il comando g (Go) a WinDbg e continua l'esecuzione dall'istruzione corrente.

Nota C'è un problema significativo passando il comando g (Go). Il problema di questo approccio è che le eccezioni non vengono sempre ripetute, in genere a causa di una condizione temporanea che non esiste più quando il codice viene riavviato. Per altre informazioni su questo problema, vedere .jdinfo (Use JIT_DEBUG_INFO).

Per evitare questo problema, usare .jdinfo o .dump /j. Questo approccio consente al debugger di trovarsi nel contesto dell'errore di codice di interesse. Per altre informazioni, vedere Debug JIT più avanti in questo argomento.

CDB

Per impostare il debugger postmortem su CDB, eseguire cdb -iae (Install AeDebug) o cdb -iaec KeyString (Installare AeDebug con Comando).

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iae

Quando si usa il parametro -iaec , KeyString specifica una stringa da aggiungere alla fine della riga di comando usata per avviare il debugger postmortem. Se KeyString contiene spazi, deve essere racchiuso tra virgolette.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe -iaec [KeyString]

Questo comando non visualizza nulla se ha esito positivo e un messaggio di errore in caso di errore.

NTSD

Per impostare il debugger postmortem su NTSD, eseguire ntsd -iae (Installa AeDebug) o ntsd -iaec KeyString (installare AeDebug con Comando).

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iae
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iae

Quando si usa il parametro -iaec , KeyString specifica una stringa da aggiungere alla fine della riga di comando usata per avviare il debugger postmortem. Se KeyString contiene spazi, deve essere racchiuso tra virgolette.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\ntsd.exe -iaec [KeyString]
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\ntsd.exe -iaec [KeyString]

Questo comando non visualizza nulla se ha esito positivo e viene visualizzato un errore in una nuova finestra della console in caso di errore.

Nota Poiché i parametri -p %ld -e %ld -g vengono sempre visualizzati per primi nella riga di comando del debugger postmortem, non è consigliabile usare l'opzione -iaec per specificare il parametro -server perché -server non funzionerà a meno che non venga visualizzato prima nella riga di comando. Per installare un debugger postmortem che include questo parametro, è necessario modificare manualmente il Registro di sistema.

Visual Studio JIT Debugger

Se Visual Studio è stato installato, vsjitdebugger.exe verrà registrato come debugger post mortem. Il debugger JIT di Visual Studio prevede che il processo venga sottoposto a debug in modo interattivo.

Debugger = "C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld

Se Visual Studio viene aggiornato o riinstallato, questa voce verrà riscritta sovrascrivendo eventuali valori alternativi impostati.

Finestra Sysinternals ProcDump

L'utilità Windows Sysinternals ProcDump può essere usata anche per l'acquisizione di dump postmortem. Per altre informazioni sull'uso e il download di ProcDump, vedere ProcDump.

Come il comando WinDbg .dump , ProcDump è in grado di acquisire un dump dell'arresto anomalo non interattivo. L'acquisizione può verificarsi in qualsiasi sessione di sistema di Windows.

ProcDump viene chiuso al termine dell'acquisizione del file di dump, wer segnala quindi l'errore e il processo di errore viene terminato.

Usare procdump -i per installare procdump e -you per disinstallare ProcDump sia per il debug post mortem a 32 che a 64 bit.

<Path>\procdump.exe -i

I comandi di installazione e disinstallazione generano l'output dei valori del Registro di sistema modificati in caso di esito positivo e gli errori in caso di errore.

Le opzioni della riga di comando ProcDump nel Registro di sistema sono impostate su:

Debugger = <Path>\ProcDump.exe -accepteula -j "<DumpFolder>" %ld %ld %p

ProcDump usa tutti e 3 i parametri: PID, Event e JIT_DEBUG_INFO. Per altre informazioni sul parametro JIT_DEBUG_INFO, vedere Debug JIT (Just In Time) di seguito.

Le dimensioni predefinite del dump acquisito sono Mini (process/threads/handle/modules/address space) senza un set di opzioni di dimensioni, MiniPlus (Mini plus MEM_PRIVATE pages) con -mp set o Full (all memory - equivalente a ".dump /mA") con -ma set.

Per i sistemi con spazio su unità sufficiente, è consigliabile usare un'acquisizione completa (ma).

Usare -ma con l'opzione -i per specificare un'acquisizione di memoria. Facoltativamente, specificare un percorso per i file di dump.

<Path>\procdump.exe -ma -i c:\Dumps

Per i sistemi con spazio su unità limitato, è consigliabile usare un'acquisizione MiniPlus (-mp).

<Path>\procdump.exe -mp -i c:\Dumps

La cartella in cui salvare il file dump è facoltativa. Il valore predefinito è la cartella corrente. La cartella deve essere protetta con un elenco di controllo di accesso uguale o superiore a quello usato per C:\Windows\Temp. Per altre informazioni sulla gestione della sicurezza correlata alle cartelle, vedere Security During Postmortem Debugging.

Per disinstallare ProcDump come debugger postmortem e ripristinare le impostazioni precedenti, usare l'opzione -u (Disinstalla).

<Path>\procdump.exe -u

Per altre informazioni su ProcDump, vedere ProcDump e Windows SysInternals Administrator's Reference by Mark Russinovich e Aaron Margosis pubblicato da Microsoft Press.

Debug JIT (Just-In-Time)

Impostazione del contesto sull'applicazione di errore

Come illustrato in precedenza, è molto consigliabile impostare il contesto sull'eccezione che ha causato l'arresto anomalo usando il parametro JIT_DEBUG_INFO. Per altre informazioni, vedere .jdinfo (Usare JIT_DEBUG_INFO)..

Strumenti di debug per Windows

In questo esempio viene illustrato come modificare il Registro di sistema per eseguire un comando iniziale (-c) che usa il comando indirizzo .jdinfo <> per visualizzare le informazioni aggiuntive sulle eccezioni e modificare il contesto in base alla posizione dell'eccezione (analogamente a come viene usato .ecxr imposta il contesto sul record di eccezione).

Debugger = "<Path>\windbg.exe -p %ld -e %ld -c ".jdinfo 0x%p"
Auto = 1

Il parametro %p è l'indirizzo di una struttura JIT_DEBUG_INFO nello spazio indirizzi del processo di destinazione. Il parametro %p viene pre-accodato con 0x in modo che venga interpretato come valore esadecimale. Per altre informazioni, vedere .jdinfo (usare JIT_DEBUG_INFO).

Per eseguire il debug di una combinazione di app a 32 e 64 bit, configurare sia le chiavi del Registro di sistema a 32 che a 64 bit (descritte in precedenza), impostando il percorso corretto sulla posizione del WinDbg.exe a 64 bit e a 32 bit.

Creazione di un file dump con estensione dump

Per acquisire un file di dump ogni volta che si verifica un errore che include i dati JIT_DEBUG_INFO, usare l'indirizzo> .dump /j<.

<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd"

Usare l'opzione /u per generare un nome file univoco per consentire la creazione automatica di più file di dump. Per altre informazioni sulle opzioni, vedere .dump (Create Dump File).

Il dump creato avrà i dati JITDEBUG_INFO archiviati come contesto di eccezione predefinito. Anziché usare .jdinfo per visualizzare le informazioni sull'eccezione e impostare il contesto, usare .exr -1 per visualizzare il record di eccezione e .ecxr per impostare il contesto. Per altre informazioni, vedere .exr (Display Exception Record) e .ecxr (Display Exception Context Record).

Segnalazione errori Windows - q/ qd

La modalità di fine della sessione di debug determina se Segnalazione errori Windows segnala l'errore.

Se la sessione di debug viene disconnessa tramite qd prima della chiusura del debugger, la segnalazione dell'errore verrà eseguita da WeR.

Se la sessione di debug viene chiusa usando q (o se il debugger viene chiuso senza scollegamento), wer non indicherà l'errore.

Accodamento ; q o ; qd alla fine della stringa di comando per richiamare il comportamento desiderato.

Ad esempio, per consentire a WeR di segnalare l'errore dopo l'acquisizione di un dump da parte di CDB, configurare questa stringa di comando.

<Path>\cdb.exe -p %ld -e %ld -c ".dump /j 0x%p /u c:\Dumps\AeDebug.dmp; qd"

Questo esempio consente a WeR di segnalare l'errore dopo che WinDbg acquisisce un dump.

<Path>\windbg.exe -p %ld -e %ld -c ".dump /j %p /u <DumpPath>\AeDebug.dmp; qd""

Vulnerabilità di sicurezza

Se si sta valutando la possibilità di abilitare il debug postmortem in un computer condiviso con altri utenti, vedere Security During Postmortem Debugging (Sicurezza durante il debug postmortem).