MultiThreaded Apps - $TIB e conditional break
Per restare su un tema caldo, visto che si va verso lo sviluppo di applicazioni managed multipiattaforma ospitate (x es. in un browser) da un CLR trimmed con strato di supporto a linguaggi dinamici (DLR) ... parliamo un po' di debug tricks per applicazioni unmanaged :-)
Qualcosa di interessante che torna alla memoria, qualcosa di nuovo che scopro ora.
Scenario: applicazione multithreaded (pesantemente), C++, necessità di debug.
Per dirla in pratica, mentre stiamo facendo step-through del codice in esecuzione nel thread A, il thread B "passa per" un breakpoint e ... pluf ... Pensate il tutto nel contesto di un sistema complesso e odierete i debugger, i thread, Windows e il giorno in cui avete scelto il vostro lavoro.
Vogliamo impostare un breakpoint che interrompa l'esecuzione dell'applicazione solo se il codice relativo viene eseguito dal thread A ?
Il trucco che ho sempre usato è quello di dichiarare una variabile globale (*solo* in debug) ed impostarne il valore all'indirizzo contenuto in fs:[18h], che punta sempre Thread Information Block (1) del thread correntemente in esecuzione.
#ifdef _DEBUG
void* g_pTIB;
#define STORE_TIB /
_asm /
{ /
mov EAX, fs:[18h] /
mov g_pTIB, eax /
} /
#else
#define STORE_TIB
#endif
E' sufficiente, infine, impostare una condizione di hit sul breakpoint.
g_pTIB == 0x........
Ovviamente il valore di test (quello relativo thread che ci interessa monitorare) va catturato durante la fase di debug (ecco spiegato il motivo di esistere della macro STORE_TIB).
Niente male, quindi, l'aver scoperto una feature di VC++ (>= 6) che ci consente di riscrivere l'espressione condizionale come segue:
$TIB == 0x........
$TIB è uno pseudoregister.
Che possiamo, appunto, consultare in fase di debug (da una watch window oppure, come sopra, in un'espressione condizionale) e che ritorna l'indirizzo del TIB del thread corrente.
Pseudoregister ? Qui trovate un bell'articolo su codeproject che ne spiega il significato e l'utilizzo.
(1) Cos'è il TIB ? E' una struttura dati, parte del Thread Environment Block (TEB). Cos'è il TEB ? E' una struttura dati che risiede all'interno della memoria del processo (in user-mode) e che mantiene diverse info relative al thread a cui si riferisce.