2009-06-01 10 views
7

È possibile che il debugger (o il gestore di eccezioni CLR) mostri la riga in cui si è verificata l'eccezione nella modalità di rilascio utilizzando il pdb?Ottenere il numero di riga dal pdb in modalità di rilascio

Il codice, in modalità di rilascio, è ottimizzato e non sempre segue l'ordine e la logica del codice "originale".

È anche sorprendente che il debugger possa navigare attraverso il mio codice passo dopo passo, anche in modalità di rilascio. L'ottimizzazione dovrebbe rendere la navigazione molto inconfiabile.

Potrebbe chiarire questi due punti per me?

risposta

10

Non ho familiarità con il modo in cui questo viene eseguito con CLR, ma probabilmente è molto simile a come è fatto con il codice nativo. Quando il compilatore genera istruzioni sulla macchina, aggiunge voci al pdb che in pratica dicono "l'istruzione all'indirizzo corrente, X, proviene dalla riga 25 in foo.cpp".

Il debugger conosce l'indirizzo del programma attualmente in esecuzione. Quindi cerca qualche indirizzo, X, nel pdb e vede che proviene dalla riga 25 di foo.cpp. Usando questo, è in grado di "passare" attraverso il codice sorgente.

Questo processo è lo stesso indipendentemente dalla modalità Debug o Release (a condizione che venga generato un pdb nella modalità di rilascio). Hai ragione, tuttavia, che spesso in modalità di rilascio a causa di ottimizzazioni il debugger non eseguirà "linearmente" il codice. Potrebbe saltare in diverse direzioni inaspettatamente. Ciò è dovuto all'ottimizzatore che modifica l'ordine delle istruzioni, ma non modifica il mapping da indirizzo a codice sorgente, quindi il debugger è ancora in grado di seguirlo.

+0

Ty per la tua risposta dettagliata. Le cose ora sono chiare per me. –

0

Il debugger fa un'ipotesi ottimale in cui si è verificato il problema. Non è garantito che sia accurato al 100% e, con un codice completamente ottimizzato, spesso sarà impreciso: ho riscontrato che le imprecisioni vanno da poche righe a uno stack di chiamate completamente errato.

L'accuratezza del debugger con il codice ottimizzato dipende molto dal codice stesso e dalle ottimizzazioni che si stanno facendo.

+1

Ty. "per avere uno stack di chiamate completamente sbagliato." la traccia dello stack non deve sempre essere accurata? –

+0

C'è una fonte o più informazioni sui numeri di linea che si spengono? Ho cancellato alcuni post su SO sull'ottimizzazione del codice di debug/pdb/compiler e non ho trovato alcun punto chiaro su questo. – gerleim

1

[@Not Certo] ha quasi giusto. Il compilatore si impegna al meglio per identificare un numero di linea appropriato che corrisponda strettamente all'istruzione corrente del codice macchina.

Il PDB e il debugger non conoscono nulla delle ottimizzazioni; il file PDB mappa essenzialmente le posizioni degli indirizzi nel codice macchina ai numeri di riga del codice sorgente. Nel codice ottimizzato, non è sempre possibile abbinare esattamente un'istruzione di assemblaggio a una specifica linea di codice sorgente, quindi il compilatore scriverà al PDB la cosa più vicina a portata di mano. Questo potrebbe essere "la riga del codice sorgente prima" o "la riga del codice sorgente del contesto (loop, ecc.)" O qualcos'altro.

Indipendentemente da ciò, il debugger trova essenzialmente la voce nella mappa PDB più vicina (come in "prima o uguale") all'IP corrente (Puntatore di istruzioni) e evidenzia quella linea.

A volte la partita non è molto buona, ed è allora che si vede l'area evidenziata che salta dappertutto.

+1

Forse il compilatore genera un diverso pdb per il rilascio e per la modalità di debug. Il pdb per la modalità di rilascio prende in considerazione l'ottimizzazione, quindi può dare una linea relativamente accurata per un'eccezione. –

+0

Oh, assolutamente. Il PDB è sempre legato alla stessa esatta istanza della DLL (o EXE) con cui è stata creata. Si noti che, anche se si ricompila nella stessa modalità, senza modifiche al file di origine, non è ancora possibile combinare i PDB e le DLL. Il tuo PDB deve essere lo stesso esatto che è stato creato quando il modulo (DLL o EXE) che si sta eseguendo il debug è stato compilato perché il compilatore potrebbe inserire in modo casuale elementi in posizioni diverse su ogni build. Era quello che stavi cercando di fare? –

+0

@Euro Micelli:> il compilatore potrebbe mettere a caso cose in posti diversi su ogni build

Problemi correlati