Condividi tramite


Abilitazione del debug postmortem

Gestione delle eccezioni in modalità utente

Eccezioni e punti di interruzione

Gli errori dell'applicazione più comuni sono denominati eccezioni. Queste includono 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 causano l'interruzione della destinazione in questo debugger.

    Purché il debugger in modalità utente sia 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 ha le proprie routine di gestione delle eccezioni (ad esempio , provare - ad eccezione), questa routine di gestione delle eccezioni tenterà di gestire l'errore.

  3. Se non è collegato alcun debugger in modalità utente e Windows ha una connessione di debug del kernel aperta e l'errore è un interruzione 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 l'interruzione della modalità utente 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 Recupero della configurazione 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 passare 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 di memoria se i valori appropriati vengono impostati nel Registro di sistema. Per altre informazioni, vedere Uso di wer e raccolta di dump di User-Mode.

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 il 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 primari 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 che il debugger postmortem venga terminato. 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 sulle eccezioni e il contesto.

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

Se l'opzione Auto è impostata 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 si modifica manualmente il Registro di sistema, farlo con attenzione, perché le modifiche non corretta al Registro di sistema potrebbero non consentire l'avvio di Windows.

Utilizzo della riga di comando di esempio

Molti debugger postmortem usano rispettivamente una riga di comando che include le opzioni -p e -e per indicare che i parametri sono un PID e Un evento (rispettivamente). 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. Ad esempio, non è necessario specificare eventuali commutatori 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 a 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 applicazioni a 64 bit e a 32 bit. Per archiviare i valori di debug dell'applicazione a 32 bit dopo mortem, 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 verrà eseguito due volte, una volta 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 di debugger Post Mortem

Strumenti di debug per Windows

Gli strumenti di debug per i debugger windows supportano tutti i supporti impostati come debugger postmortem. Il comando di installazione intende eseguire il debug interattivo del processo.

WinDbg

Per impostare il debugger postmortem su WinDbg, eseguire windbg -I. (Deve I essere maiuscolo). Questo comando visualizzerà un messaggio di esito positivo o negativo dopo l'uso. Per usare sia applicazioni a 32 che 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

Si tratta del modo in cui la voce del Registro di sistema AeDebug verrà configurata 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.

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

Nota Si verifica un problema significativo passando il comando g (Go). Il problema con questo approccio è che le eccezioni non si ripetano sempre, 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 (Usare 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 (Just In Time) più avanti in questo argomento.

CDB

Per impostare il debugger postmortem su CDB, eseguire cdb -iae (Install AeDebug) o cdb -iaecKeyString (Install AeDebug with Command).

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 viene usato 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 se ha esito negativo.

NTSD

Per impostare il debugger postmortem su NTSD, eseguire ntsd -iae (Install AeDebug) o ntsd -iaecKeyString (Install AeDebug with Command).

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 viene usato 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 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. Visual Studio JIT Debugger prevede il debug interattivo del processo.

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

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

Finestra Sysinternals ProcDump

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

Analogamente al comando WinDbg con estensione 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, viene quindi segnalato 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 i 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 tre 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 di dump acquisite 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 - equivalenti a ".dump /mA") con -ma set.

Per i sistemi con spazio su unità sufficiente, è consigliabile 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 disco 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 Sicurezza durante il debug postmortem.

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 and Aaron Margosis published by Microsoft Press.For additional information on ProcDump, see ProcDump and Windows SysInternals Administrator's Reference by Mark Russinovich and Aaron Margosis published by 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 con estensione jdinfo <address> per visualizzare le informazioni aggiuntive sull'eccezione e modificare il contesto in base alla posizione dell'eccezione (analogamente al modo in cui 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 appropriato sulla posizione del WinDbg.exe a 64 bit e a 32 bit.

Creazione di un file dump con estensione dump

Per acquisire un file 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 usando qd prima della chiusura del debugger, verrà visualizzato l'errore.

Se la sessione di debug viene chiusa usando q (o se il debugger è chiuso senza scollegare), il ripristino errori non verrà visualizzato.

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 l'abilitazione del debug postmortem in un computer condiviso con altre persone, vedere Security During Postmortem Debugging (Sicurezza durante il debug postmortem).