17

Con g ++ con -g option, posso utilizzare gdb per scopi di debug.L'opzione g ++ -g equivalente al compilatore cl VS2010?

Qual è l'equivalente di questa opzione con il compilatore di Visual Studio 2010 cl.exe?

Questo page dispone di librerie diverse (debug/release) per il collegamento.

Se compilo con l'opzione di debug con cl.exe, devo utilizzare le opzioni di collegamento della libreria corrispondente (/ MD/MT vs/MDd/MTd)?

risposta

29

Ci sono alcuni pezzi separati a questa domanda: come dire al compilatore/linker di generare e conservare "informazioni di debug" (mappatura tra codice sorgente e codice oggetto), come dire al compilatore di compilare il codice in modo diverso per facilita il debug (pensa a assert() e #ifdef _DEBUG), e se le librerie precompilate che inserisci nel tuo progetto includono le informazioni di debug.

-Zi (contrassegna al compilatore CL per indicare che genera informazioni di debug) equivale al flag gcc -g.

(Esistono altre forme dell'opzione -Z: -ZI se si desidera il supporto "modifica e continua" nell'IDE di Visual Studio, ma se si sta utilizzando l'IDE probabilmente si sta utilizzando la sua interfaccia per le impostazioni del compilatore invece di manipolarle direttamente e -Z7 se vuoi le vecchie informazioni di debug in formato CodeView, ogni volta che ho richiamato CL direttamente è sempre stato -Zi che volevo.)

Nota che usando -Zi (o -ZI) genererà un file .pdb per directory, di solito, ma quando si collega il codice insieme, potrebbe provenire da file .obj rappresentati in diversi file .pdb, e si desidera anche combinare quei file .pdb separati in un master uno che rappresenta il codice che hai collegato insieme - questo è ciò che è per l'opzione -debug per il linker.

Nota anche: questo può sembrare controintuitivo, ma utilizzare sempre -Zi (per CL) e -debug (per link.exe). Anche per il codice che rilascerai. Non aumenta la dimensione del tuo eseguibile, né offre segreti ai tuoi clienti, poiché le informazioni di debug si trovano in un file .pdb separato (che non invierai ai clienti). Se c'è qualche possibilità che tu debba eseguire il debug, vorresti il ​​.pdb. (-Zi non è nemmeno incompatibile con le ottimizzazioni, anche se -ZI è. Quindi potresti voler compilare le build "debug" con -ZI, e il tuo "release" costruisce con "-Zi -O2".)

Per quanto riguarda le librerie: non è strettamente necessario abbinare la proprietà debug/release della libreria di runtime C con il fatto che il tuo codice includa le informazioni di debug, ma di solito è una buona idea - se hai intenzione di eseguire il debug del progetto che vuoi essere in grado di eseguire il debug di tutto, e se non hai intenzione di eseguire il debug di esso non è necessario il peso extra. L'uso delle versioni di debug/release di una determinata libreria non influirà sulla disponibilità dei simboli di debug (si spera che se chiunque abbia compilato la libreria abbia compreso il punto che ho fatto nel paragrafo precedente), ma avrà effetto cose come assert e extra #ifdef _DEBUG codice in quella libreria.

Questo vale per tutte le librerie con cui si effettua il collegamento, ma soprattutto per la libreria di runtime C: Microsoft ha aggiunto un ulteriore codice di rilevamento degli errori a malloc() e free(). Quindi, se qualcosa nel tuo progetto sta usando l'aroma di debug della libreria CRT, dovrebbe essere tutto.

Le opzioni/M (/ MTd e/MDd) sono strane e magiche, secondo me - sono solo alias per una serie complicata di altre cose in corso dietro le quinte. Prendiamo ad esempio/MDd, documentato in "Definisci _DEBUG, _MT e _DLL e fa in modo che l'applicazione utilizzi la versione di debug multithread e DLL specifica della libreria di runtime e fa in modo che il compilatore inserisca il nome della libreria MSVCRTD. lib nel file .obj. " Qui, sta interessando sia il preprocessore (che definisce _DEBUG e alcuni altri simboli del preprocessore) sia il linker (in realtà inserisce un commento #pragma (linker) nel codice sorgente). Se ti interessa cosa sta succedendo e non lo capisci, questo può causare problemi reali - Ho visto molti progetti che non usano l'IDE impantanarsi negli avvisi riguardanti sia msvcrt.lib che msvcrtd.lib essere collegato in, ecc. Nel momento in cui capisci come usare queste (opzioni/M) in modo sicuro, non ne hai più bisogno! Preferisco rendere le cose esplicite: specificare "-D _DEBUG" direttamente dove mi serve, specificare le librerie da collegare esplicitamente (e usare -nodefaultlib), e quindi le opzioni/M non sono necessarie.

+4

+1 Wow. Posso chiedere come sei diventato così familiare con le idiosincrasie della toolchain di Microsoft? :) –

+9

Anni e anni di utilizzo di diverse versioni di MSVC, molti progetti crossplatform quindi usavamo makefile o altrimenti bypassando il sistema di build dell'IDE, utilizzando librerie open-source costruite da terze parti, mantenendo il tutto funzionante attraverso gli aggiornamenti alle nuove versioni di MSVC o SDK, ecc. :) – metamatt

6

Siete alla ricerca di uno dei debug information generation options (/Z7, /Zi o /ZI).

Se si utilizza uno di questi, è necessario passare anche l'opzione /DEBUG al linker.

È inoltre necessario eseguire il collegamento con lo debug version delle librerie di runtime (/MDd o /MTd). Questo è importante perché queste versioni sono diverse dalle loro controparti di rilascio (ad esempio, le loro routine di allocazione di memoria non sono compatibili).