2014-12-31 6 views
5

Ogni volta che ottengo un crash dump per una versione x64 della mia applicazione, trovo che sia raro che riesca a visualizzare i locali, questo rende difficile o impossibile risolvere alcuni problemi. In x86 di solito riesco a visualizzare tutti i locali senza problemi.Esistono opzioni di compilazione per rendere più utilizzabili i dump di arresto del rilascio x64?

Ci sono alcune opzioni del compilatore nella versione di rilascio che mi consentiranno di visualizzare i locali nei dump di arresto di generazione di build? Ovviamente non voglio disattivare le ottimizzazioni, ma forse c'è un modo per costringerlo a salvare i locali con un minore impatto sulle prestazioni?

+0

Hai pensato di passare a qualche altro compilatore come [GCC] (http://gcc.gnu.org/) o [Clang/LLVM] (http://clang.llvm.org/)? Puoi compilare sia con le informazioni di debug che con le ottimizzazioni (es. 'G ++' o 'clang' con' -O2 -g') –

+0

I locali tendono ad essere ottimizzati, quindi no, non puoi "avere la tua torta e mangiarla", in generale. –

+1

Non aspettatevi che la versione/build ottimizzata sia di facile lettura. x86_64 ha molti più registri, quindi il compilatore non dovrà versare molte variabili in memoria, questo potrebbe essere uno dei motivi per cui non hai visto i valori. –

risposta

10

Hai detto un paio di cose che suggeriscono il motivo per cui non si può vedere la gente del posto ...

# 1 - E 'una build di rilascio.

Con alcune ottimizzazioni attivate, il compilatore è libero di fare alcune cose che rendono più difficile la ricerca dei locali.

  1. Una funzione può essere impostata su inline. Quando ciò accade, i locali della funzione che non sono ottimizzati vengono mescolati con il frame dello stack chiamante.
  2. È possibile liberare un registro e salvare un paio di cicli di clock sulla chiamata di funzione utilizzando un trucco chiamato Frame-Pointer Omission.
  3. Per risparmiare spazio nello stack, il compilatore può immettere reuse the location in precedenza una variabile nel corpo della funzione per mantenere una variabile diversa in seguito nella funzione. Ciò significa che dove ti trovi nella funzione determina quali persone locali sei effettivamente in grado di vedere.

# 2 - È una versione x64.

MSVC utilizza una nuova convenzione di chiamata per codice a 64 bit denominata in modo appropriato x64 Calling Convention. I primi 4 argomenti di funzione sono memorizzati in registri anziché nello stack. Ciò significa che anche se stai guardando uno stack frame, non vedrai alcuni degli argomenti e potresti persino non riuscire a recuperarli se i registri sono stati riutilizzati per qualcos'altro prima che li guardi.


Quindi, e adesso?

Ora che sappiamo perché avrai un momento così difficile, vediamo cosa puoi fare per risolvere i problemi sopra descritti. Nessuno di questi problemi è davvero un ostacolo, ma tutti lavorano insieme per rendere le cose ancora più difficili per te.

  1. Disattivare alcune ottimizzazioni. È possibile provare a creare con una build di rilascio con ottimizzazioni a un livello che non impedisca il debug in modo eccessivo. Probabilmente vorrai iniziare con le ottimizzazioni menzionate sopra che giocano con i frame dello stack (/ Oy e/Ob). Quindi dovresti sperare che tu possa ancora riprodurre il problema con quelle ottimizzazioni disattivate. Inoltre, a seconda della tua politica interna e del contratto che hai con il tuo cliente, potresti dover coinvolgere un avvocato prima di inviare una build non ufficiale al cliente - probabilmente non è la cosa più divertente del mondo.

  2. Creare un file di simboli migliore. VS2012 e versioni successive ha un nuovo interruttore del compilatore, /d2Zi+ in VS2012 e /Zo in VS2013, che genera informazioni di debug migliori quando vengono attivate le ottimizzazioni. Questo mette il debugging del codice ottimizzato alla pari con GCC/Clang. Anche se non è documentato in VS2012, lo considererei comunque abbastanza sicuro poiché non ho visto alcuna differenza nel codice generato - solo nel file dei simboli. Potresti anche essere in grado di ricostruire localmente con questo flag e forzare windbg a utilizzare il nuovo file di simboli tramite .symopt+ 0x40. Questo ti dà la possibilità di ottenere di più dalle discariche che hai già.

  3. Utilizzare le estensioni del windbg per effettuare il sollevamento pesante. In other StackOverflow answers, ho menzionato uno strumento chiamato CMKD che ha salvato il mio bacon un paio di volte. Tra l'altro, tenta di ricostruire gli argomenti nella convenzione di chiamata x64 che sono stati passati nei registri. Non è una cosa sicura, ma è probabilmente la migliore speranza di farli tornare.

In ogni caso, spero che le mie divagazioni possano rivelarsi utili nel debugging.

+0

CMKD sembra fare il lavoro :) Proverò questo/Opzione Zo anche – paulm

+1

Devi assolutamente aggiungere/Zo per ottenere un miglior monitoraggio dei locali. Funziona particolarmente bene durante il debug con windbg (mostra inlining), ma funziona anche con VC++. Ci sono un paio di disposizioni - il mio post sul blog le riguarda: https://randomascii.wordpress.com/2013/09/11/debugging-optimized-codenew-in-visual-studio-2012/ –

Problemi correlati