2014-04-01 18 views
9

std::unique_ptr sono buoni, ma li trovo meno comodi durante il debug in DDD o gdb.Come eseguire il debug del codice C++ 11 con unique_ptr in DDD (o gdb)?

Sto utilizzando le stampanti gdb pretty che fanno parte di gcc (ad es., /usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py). Questa è una grande vittoria per la leggibilità, ad esempio:

$ print pTest 
std::unique_ptr<MyType> containing 0x2cef0a0 

Tuttavia, dereferenziazione il puntatore non funziona:

$ print *pTest 
Could not find operator*. 

Quando ho bisogno di accedere al valore, devo copiare manualmente il puntatore e il cast al tipo corretto, ad esempio:

print *((MyType*) 0x2cef0a0) 

Se il processo è ancora in esecuzione, questa versione funziona (ancora brutto, ma meglio):

print *pTest.get() // will not work if analyzing a core dump 

L'approccio diretto a Display *pTest in DDD non funziona. Essa si traduce solo nel seguente errore:

<error: Could not find operator*.> 

C'è un modo per eseguire il debug C++ 11 codice con unique_ptr a DDD (senza rompere il flusso di lavoro come faccio con le mie soluzioni ingombranti)?


Non ho paura di utilizzare i comandi gdb, ma l'integrazione DDD sarebbe un vantaggio. Ad esempio, seguire i puntatori nelle strutture dati semplicemente facendo doppio clic su di essi è spesso più veloce della digitazione.

Ho già provato a rilasciare la stampante carina, ma non è ottimale. Il meglio che ho potuto venire in mente è la seguente:

print pTest._M_t->_M_head_impl 
+0

può sembrare una domanda stupida, ma ha fatto si deve costruire il compilatore gcc sulla tua confezione da zero? O era un aggiornamento RPM? Recentemente ho avuto un problema con gdb quando ho provato a eseguire il debug di un codice C++ 11 e ho scoperto che non avrei ricompilato gdb. Sono abbastanza sicuro che non sia il caso, ma ho pensato che valesse la pena di chiedermelo. – Welshboy

+0

@Welshboy Attualmente sto usando il gcc ufficiale 4.8.2 (20140206) e gdb 7.7 di Arch Linux. –

+1

Si potrebbe provare questo: http://stackoverflow.com/questions/322322/displaying-dereferenced-stl-iterators-in-gdb e in particolare dare un'occhiata a un file gdbinit. Sembra che ci siano molte cose personalizzate che puoi fare con gdb. In bocca al lupo. – Ben

risposta

7

Questo problema è in realtà non legati al C++ 11, unique_ptr o piuttosto la stampa. Il problema è che gcc non emette codice per std :: unique_ptr :: operator * che potrebbe essere chiamato da gdb per dereferenziare unique_ptr. Se ad esempio aggiungi *pTest; al tuo codice allora gdb esegue il dereferenziamento.

Un problema simile è descritto nel post SO How to `print`/evaluate c++ template functions in gdb. Quasi lo stesso problema è descritto per un auto_ptr a https://sourceware.org/ml/archer/2012-q1/msg00003.html. Se capisco il thread in modo corretto, una soluzione sarebbe quella di patchare la bella stampante e anche stampare il puntatore senza riferimenti quando si stampa il unique_ptr. Un bug report gdb può essere trovato a http://sourceware.org/bugzilla/show_bug.cgi?id=12937.

Il wiki gdb a https://sourceware.org/gdb/wiki/STLSupport descrive più soluzioni di stampa carine, che potrebbero avere altri metodi.

Edit: una soluzione più elegante costringendo il compilatore ad emettere il codice per tutti i modelli di membro tra operatore * è quello di istanziare esplicitamente la classe:

template class std::unique_ptr<MyType>; 
+0

dove dovrei definire questa istanziazione esplicita? – q0987

+0

Da un punto di vista tecnico in una delle tue unità di traduzione ("cpp file") dopo aver incluso l'intestazione 'memory' e dopo la dichiarazione di' MyType' (o la rispettiva inclusione) - vedi http: //en.cppreference .com/w/cpp/lingua/class_template # Explicit_instantiation – user1225999