2009-01-11 15 views
45

Debugging con gdb, qualsiasi codice C++ che usi STL/boost è ancora un incubo. Chiunque abbia usato gdb con STL lo sa. Ad esempio, consultare le esecuzioni di esempio di alcune sessioni di debug nel codice here.Debug delle best practice per C++ STL/Boost con gdb

Sto cercando di ridurre il dolore raccogliendo punte. Puoi commentare i suggerimenti che ho raccolto di seguito (in particolare quelli che hai utilizzato e le eventuali modifiche che consiglieresti su di essi) - Ho elencato i suggerimenti in ordine decrescente di tecnicità.

  • C'è qualcuno che utilizza "Stanford GDB STL utils" e "UCF GDB utils"? Esistono alcuni programmi di questo tipo per le strutture dati di boost? Gli strumenti di cui sopra non sembrano essere utilizzabili in modo ricorsivo, ad esempio per stampare il vettore di un boost :: shared_ptr in modo leggibile all'interno di un comando.
  • Scrivi il tuo file .gdbinit. Includere, ad esempio, abbellimenti correlati a C++, elencati nella parte inferiore dei programmi di utilità GDB di UCF.
  • Utilizzare la libreria STL/Boost selezionata/debug, come STLport.
  • utilizzare la registrazione (ad esempio come descritto here)

Aggiornamento: GDB ha un new C++ branch.

+1

chiesto e ha risposto, ma gdb 7 ha molto migliore supporto per i contenitori STL - la nostra installazione out-of-the-box include il supporto per la stampa come "$ 4 = std :: vector of length 4, capacity 4 = {0, 2, 4, 888}". Non ho visto cosa fa con tipi complessi o altri contenitori, ma sembra un enorme miglioramento. Vedi [questa pagina] (http://sourceware.org/gdb/wiki/STLSupport) per maggiori dettagli ... –

+0

@RobI Grazie! Tuttavia, con mia grande sofferenza ho trovato che il supporto basato su Python manca ancora quando uso i contenitori di puntatori boost, cosa che faccio spesso. GDB continua semplicemente a lamentarsi e non a stampare i contenuti. –

risposta

16
non

Forse il tipo di "punta" che stavate cercando, ma devo dire che la mia esperienza, dopo alcuni anni di spostamento da C++ & STL a C++ & boost & STL è che ora spendo un lotto meno tempo in GDB di quanto facevo prima. Ho messo questo fino a un certo numero di cose:

  • spinta puntatori intelligenti ("puntatore condiviso" particolarmente, ed i contenitori puntatore quando è necessario prestazioni).Non riesco a ricordare l'ultima volta che ho dovuto scrivere una cancellazione esplicita (delete è il "goto" di C++ IMHO). C'è un sacco di tempo GDB rintracciare i puntatori non validi e che perdono.
  • boost è pieno di codice comprovato per cose che probabilmente avresti dovuto mettere insieme una versione inferiore di altrimenti. ad esempio boost::bimap è ottimo per lo schema comune della logica di memorizzazione nella cache di LRU. C'è un altro mucchio di tempo GDB.
  • Adottare l'unittesting. I macro AUTO di boost::test significano che è un assoluto gioco di test (easier than CppUnit). Questo prende un sacco di cose molto prima che venga incorporato in tutto ciò a cui dovresti collegare un debugger.
  • In relazione a ciò, strumenti come boost::bind semplificano la progettazione per il test. ad esempio, gli algoritmi possono essere più generici e meno legati ai tipi su cui operano; ciò rende più facile collegarli a shim test/proxy/oggetti finti, ecc. (il fatto che l'esposizione alla durezza del modello di boost ti incoraggerà a "osare un modello" di cose che non avresti mai considerato prima, ottenendo benefici simili per i test).
  • boost::array. Prestazioni "C array", con controllo dell'intervallo nelle build di debug.
  • spinta è piena di grande codice non si può fare a meno di imparare da
+3

> boost è pieno di grande codice che non puoi fare a meno di imparare da Sono sicuro d'accordo, ma per i principianti è un'enorme collina da scalare. Hanno paura quando vedono messaggi di errore del compilatore di mezza pagina. –

+1

Molto vero! Un consiglio utile è di incollarli in un editor e cercare e sostituire ad esempio std :: basic_string con STRING e ridurre le cose a qualcosa di comprensibile (in genere è il "livello più alto" a cui sei interessato, non il dettaglio). – timday

+0

Se è possibile utilizzare C++ 11, notare che i puntatori intelligenti di boost fanno ora parte della libreria standard in C++ 11 – Triskeldeian

3

Penso che l'opzione più semplice e più è quella di utilizzare la registrazione (beh, in realtà io uso le stampe di debug, ma penso che non sia un punto). Il più grande vantaggio è che è possibile ispezionare qualsiasi tipo di dati, molte volte per l'esecuzione del programma e quindi cercarlo con un editor di testo per cercare dati interessanti. Si noti che questo è molto veloce. Lo svantaggio è ovvio, è necessario preselezionare i dati che si desidera registrare e luoghi da registrare. Tuttavia, non è un problema così grave, perché di solito sai dove stanno accadendo cose brutte nel codice (e se no, aggiungi solo controlli di sanità qui e là e poi, lo saprai).

Le librerie controllate/debug sono buone, ma sono migliori come strumento di test (ad esempio eseguirlo e vedere se sto facendo qualcosa di sbagliato), e non altrettanto bene nel debug di un problema specifico. Non riescono a rilevare un difetto nel codice utente.

Altrimenti, utilizzo semplicemente GDB. Non è così male come sembra, anche se potrebbe essere se hai paura di "print x" stampare una schermata di spazzatura. Tuttavia, se si esegue il debug di informazioni, ad esempio la stampa di un membro di un std::vector e se qualcosa non funziona, è comunque possibile ispezionare la memoria non elaborata tramite il comando x. Ma se so cosa sto cercando, io uso l'opzione 1 - logging.

Si noti che le strutture "difficili da ispezionare" non sono solo STL/Boost, ma anche da altre librerie, come Qt/KDE.

Problemi correlati