Procedura: eseguire il debug di codice ottimizzato
Le informazioni contenute in questo argomento sono valide per:
Edizione |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
Express |
Solo nativo |
||||
Pro, Premium e Ultimate |
Solo nativo |
Nota
È possibile che le finestre di dialogo e i comandi di menu visualizzati siano diversi da quelli descritti nella Guida a seconda delle impostazioni attive o dell'edizione del programma. Per modificare le impostazioni, scegliere Importa/Esporta impostazioni dal menu Strumenti. Per ulteriori informazioni, vedere Gestione delle impostazioni.
Quando il compilatore ottimizza il codice, modifica la posizione e l'organizzazione delle istruzioni. IL risultato è un codice compilato più efficace. A causa di questa ridisposizione, il debugger non è sempre in grado di identificare il codice sorgente corrispondente a un set di istruzioni.
L'ottimizzazione del codice può influenzare:
Le variabili locali, che possono essere rimosse o spostate in posizioni non riconosciute dal debugger
Le posizioni all'interno di una funzione, che vengono modificate quando l'utilità di ottimizzazione esegue l'unione di blocchi di codice.
I nomi delle funzioni per i frame nello stack di chiamate, che potrebbero risultare errati se due funzioni vengono unite.
I frame visualizzati nello stack di chiamate sono in genere corretti, se si dispone di simboli per ciascuno di essi. I frame nello stack di chiamate risulteranno errati se lo stack è danneggiato, se sono presenti funzioni scritte in linguaggio assembly oppure se esistono frame del sistema operativo privi di simboli corrispondenti nello stack di chiamate.
Le variabili globali e di tipo statico vengono visualizzate sempre correttamente, analogamente al layout delle strutture. Se si dispone di un puntatore a una struttura e il valore di questo puntatore è corretto, tutte le variabili membro della struttura conterranno il valore corretto.
A causa di queste limitazioni, è opportuno eseguire il debug utilizzando, se possibile, una versione del programma non ottimizzata. Per impostazione predefinita l'ottimizzazione è disattivata nella configurazione di debug di un programma Visual C++ e attivata nella configurazione per il rilascio.
Può tuttavia accadere che un bug venga individuato solo nella versione ottimizzata di un programma. In tal caso è necessario effettuare il debug del codice ottimizzato.
Per attivare l'ottimizzazione nella configurazione di una build di debug
Quando si crea un nuovo progetto, selezionare la destinazione Win32 Debug. Utilizzare la destinazione Win32Debug fino a quando non viene completato il debug del programma e non si è pronti a compilare una destinazione Win32 Release. Il compilatore non ottimizza la destinazione Win32 Debug.
Selezionare il progetto in Esplora soluzioni.
Scegliere Pagine delle proprietà dal menu Visualizza.
Nella finestra di dialogo Pagine delle proprietà verificare che sia selezionato Debug nell'elenco a discesa Configurazione.
Nella struttura di cartelle visualizzata sulla sinistra selezionare la cartella C/C++.
Nella cartella C++ selezionare Optimization.
Nell'elenco di proprietà situato a destra cercare Optimization. L'impostazione accanto a tale opzione sarà probabilmente Disabled (/Od). Scegliere una delle altre opzioni (Minimum Size (/O1), Maximum Speed (/O2), Full Optimization (/Ox) o Custom).
Se si è scelto l'opzione Custom per Optimization, a questo punto è possibile impostare le opzioni per le altre proprietà presenti nell'elenco.
Quando si effettua il debug di codice ottimizzato, controllare nella finestra Disassembly quali istruzioni vengono effettivamente create ed eseguite. Nell'impostazione di punti di interruzione, è necessario sapere che un punto di interruzione può essere spostato insieme a un'istruzione. Si consideri il codice di esempio seguente:
for (x=0; x<10; x++)
Si supponga di impostare un punto di interruzione in questa riga. Ci si aspetterebbe che il punto di interruzione venga raggiunto 10 volte, ma se il codice è ottimizzato, il punto di interruzione verrà raggiunto solo una volta. Ciò è dovuto al fatto che la prima istruzione imposta il valore di x su 0. Il compilatore riconosce che questa operazione deve essere eseguita solo una volta ed esce dal ciclo. Il punto di interruzione si sposta con essa. Le istruzioni che confrontano e incrementano x rimangono all'interno del ciclo. Quando si visualizza la finestra Disassembly, l'unità di esecuzione viene impostata automaticamente su Istruzione per consentire un maggiore controllo, utile se si esegue il codice un'istruzione alla volta.