Controllo di thread e processi

Per una panoramica dei thread e dei processi nel motore del debugger, vedere Thread e processi.

Quando si verifica un evento, il thread di evento e il processo di evento vengono impostati sul thread e sul processo (sistema operativo o virtuale) in cui si è verificato l'evento. Sono disponibili usando rispettivamente GetEventThread e GetEventProcess.

Thread e processi impliciti

Nel debug in modalità kernel il motore del debugger userà il processo implicito per determinare quale spazio indirizzi virtuale usare quando si esegue la conversione di indirizzi fisici da virtuale a fisico, ad esempio nei metodi VirtualToPhysical e ReadVirtual. Quando si verifica un evento, il processo implicito viene impostato sul processo corrente.

Il processo implicito può essere modificato usando SetImplicitProcessDataOffset. Per determinare il processo implicito, usare GetImplicitProcessDataOffset.

Nota Quando si impostano punti di interruzione durante una sessione di debug del kernel attivo, il motore del debugger passerà l'indirizzo virtuale del punto di interruzione alla destinazione e la destinazione imposterà il punto di interruzione. In questo caso, viene utilizzato solo il contesto del processo della destinazione quando si gestisce il punto di interruzione; il valore del processo implicito è irrilevante.

Nel debug in modalità kernel, il motore del debugger userà il thread implicito per determinare alcuni registri della destinazione. Ciò include lo stack del processore (vedere GetStackOffset), l'offset dei fotogrammi (vedere GetFrameOffset) e l'offset delle istruzioni (vedere GetInstructionOffset). Quando si verifica un evento, il thread implicito viene impostato sul thread corrente.

Il thread implicito può essere modificato usando SetImplicitThreadDataOffset. Per determinare il thread implicito, usare GetImplicitThreadDataOffset.

Non tutti i registri sono determinati dal thread implicito. Alcuni registri rimarranno invariati quando il thread implicito viene modificato.

Avviso Il processo implicito e il thread implicito sono indipendenti. Se il thread implicito non appartiene al processo implicito, lo stato dell'utente e della sessione per il thread implicito si troverà nello spazio indirizzi virtuale errato e i tentativi di accedere a queste informazioni causeranno errori o forniranno risultati non corretti. Questo problema non si verifica quando si accede alla memoria del kernel, poiché gli indirizzi di memoria del kernel sono costanti in tutti gli spazi di indirizzi virtuali. Le informazioni per il thread implicito che si trova nella memoria del kernel possono quindi essere accessibili indipendentemente dal processo implicito.

Discussioni

L'ID del thread del motore viene usato dal motore di debugger per identificare ogni thread del sistema operativo e ogni thread virtuale per una destinazione.

Mentre una destinazione viene arrestata, ogni thread ha anche un indice relativo al processo a cui appartiene. Per qualsiasi processo, l'indice del primo thread nel processo è zero e l'indice dell'ultimo thread è il numero di thread nel processo meno uno. Il numero di thread nel processo corrente è disponibile usando GetNumberThreads. Il numero totale di thread in tutti i processi nella destinazione corrente è disponibile usando GetTotalNumberThreads.

L'ID thread del motore e l'ID del thread di sistema per uno o più thread nel processo corrente sono disponibili nell'indice usando GetThreadIdsByIndex.

Il motore gestisce diverse informazioni su ogni thread. Queste informazioni possono essere sottoposte a query per il thread corrente e possono essere usate per trovare l'ID del thread del motore per un thread.

ID thread di sistema (solo debug in modalità utente)
L'ID del thread di sistema del thread corrente è reperibile usando GetCurrentThreadSystemId. Per un ID thread di sistema specifico, è possibile trovare l'ID del thread del motore corrispondente usando GetThreadIdBySystemId.

blocco di ambiente thread (TEB)
L'indirizzo del teb per il thread corrente è reperibile usando GetCurrentThreadTeb. Per un determinato indirizzo TEB, è possibile trovare l'ID del thread del motore corrispondente usando GetThreadIdByTeb. Nel debug in modalità kernel, il TEB di un thread (virtuale) è il TEB del thread di sistema in esecuzione nel processore corrispondente quando si è verificato l'ultimo evento.

offset dei dati
Nel debug in modalità utente, l'offset dei dati di un thread (sistema) è la posizione del TEB per tale thread. Nel debug in modalità kernel l'offset dei dati di un thread (virtuale) è la struttura KTHREAD per il thread di sistema in esecuzione nel processore corrispondente quando si è verificato l'ultimo evento. L'offset dei dati del thread corrente è disponibile usando GetCurrentThreadDataOffset. Per un determinato offset di dati, è possibile trovare l'ID del thread del motore corrispondente usando GetThreadIdByDataOffset.

handle di sistema
L'handle di sistema del thread corrente è disponibile usando GetCurrentThreadHandle. Per un handle di sistema specifico, è possibile trovare l'ID del thread del motore corrispondente usando GetThreadIdByHandle. Nel debug in modalità kernel viene creato un handle artificiale per ogni processo (virtuale). Questo handle può essere usato solo con le query dell'API del motore di debugger.

Processi

L'ID del processo del motore viene usato dal motore di debugger per identificare ogni processo del sistema operativo e ogni processo virtuale per una destinazione.

Mentre una destinazione viene arrestata, ogni processo ha un indice relativo alla destinazione. L'indice del primo processo nella destinazione è zero e l'indice dell'ultimo processo è il numero di processi nella destinazione meno uno. Il numero di processi nella destinazione corrente è reperibile usando GetNumberProcesses.

L'ID processo del motore e l'ID del processo di sistema per uno o più thread nella destinazione corrente possono essere trovati dall'indice usando GetProcessIdsByIndex.

Il motore gestisce diverse informazioni su ogni processo. Queste informazioni possono essere sottoposte a query per il processo corrente e possono essere usate per trovare l'ID del processo del motore per un processo.

ID processo di sistema (solo debug in modalità utente)
L'ID del processo di sistema del processo corrente è reperibile usando GetCurrentProcessSystemId. Per un ID processo di sistema specifico, è possibile trovare l'ID del processo del motore corrispondente usando GetProcessIdBySystemId.

blocco dell'ambiente di elaborazione (PEB)
L'indirizzo del peb per il processo corrente è reperibile usando GetCurrentProcessPeb. Per un determinato indirizzo PEB, è possibile trovare l'ID del processo del motore corrispondente usando GetProcessIdByPeb. Nel debug in modalità kernel, il PEB del processo (virtuale) è il PEB del processo di sistema in esecuzione quando si è verificato l'ultimo evento.

offset dei dati
Nel debug in modalità utente, l'offset dei dati di un processo (sistema) è la posizione del PEB di tale processo. Nel debug in modalità kernel, l'offset dei dati del processo (virtuale) è la struttura KPROCESS per il processo di sistema in esecuzione quando si è verificato l'ultimo evento. L'offset dei dati del processo corrente è disponibile usando GetCurrentProcessDataOffset. Per un determinato offset di dati, è possibile trovare l'ID del processo del motore corrispondente usando GetProcessIdByDataOffset.

handle di sistema
L'handle di sistema del processo corrente è disponibile usando GetCurrentProcessHandle. Per un handle di sistema specifico, è possibile trovare l'ID del processo del motore corrispondente usando GetProcessIdByHandle. Nel debug in modalità kernel viene creato un handle artificiale per il processo (virtuale). Questo handle può essere usato solo con le query del motore di debugger.

Eventi

Nel debug in modalità utente in tempo reale, ogni volta che viene creato o chiuso un thread in una destinazione, vengono generati gli eventi di debug create-thread e exit-thread. Questi eventi generano chiamate ai metodi di callback IDebugEventCallbacks::CreateThread e IDebugEventCallbacks::ExitThread .

Nel debug in modalità utente in tempo reale, ogni volta che un processo viene creato o esce in una destinazione, vengono generati gli eventi di debug create-process e exit-process. Questi eventi generano chiamate ai metodi di callback IDebugEventCallbacks::CreateProcess e IDebugEventCallbacks::ExitProcess .

Per altre informazioni sugli eventi, vedere Monitoraggio degli eventi.

Informazioni aggiuntive

Per altre informazioni su thread e processi, tra cui le strutture TEB, KTHREAD, PEB e KPROCESS, vedere Microsoft Windows Internals di David Solomon e Mark Russinovich.