2013-07-23 11 views
18

seguito è il mio codice sorgente:Esaminare shared_ptr spinta con gdb

#include <iostream> 
#include <boost/shared_ptr.hpp> 

class MyClass 
{ 
    public: 
     MyClass() 
     { 
      i=10; 
     } 
    private: 
     int i; 
}; 


int main(int argc, const char *argv[]) 
{ 
    boost::shared_ptr <MyClass> obj(new MyClass()); 
    return 0; 
} 

voglio esaminare obj in gdb, e visualizzare il valore della variabile membro i.

Questo è ciò che ottengo con la stampa normale:

29   boost::shared_ptr <MyClass> obj(new MyClass()); 
(gdb) n 
30   return 0; 
(gdb) p obj 
$1 = {px = 0x602010, pn = {pi_ = 0x602030}} 

ho provato la punta di cui al this link, ma non funziona.

(gdb) call (obj.get())->print() 
Cannot evaluate function -- may be inlined 

C'è qualche altro modo? la versione di gdb è 7.0.1.

+0

Un altro buon vecchio amico è printf semplice:) –

+1

@ Anand Rathi ..., sì, ma volevo solo sapere se questo è possibile con gdb. –

risposta

28

Trovato.!

(gdb) set print pretty 
(gdb) p obj 
$5 = { 
    px = 0x602010, 
    pn = { 
    pi_ = 0x602030 
    } 
} 
(gdb) p obj.px 
$6 = (MyClass *) 0x602010 



(gdb) p *(obj.px) 
$7 = { 
    i = 10 
} 
+3

Questa è la cosa più utile che ho visto tutto il giorno !!! Grazie mille. Non mi rendevo conto che potevo dereferenziare il puntatore in quel modo. :-) – kmort

+3

Questo non funziona per me. "p obj" restituisce '$ 2 = std :: shared_ptr (count 2, weak 1) 0x639268', e" p obj.px "restituisce" Nessun membro o metodo chiamato px'. Ho anche provato "p * obj", ma nessuna gioia: 'Impossibile trovare l'operatore * .' –

0

Sarà difficile rispondere a questa domanda. GDB 7.x ha aggiunto il supporto per lo scripting Python. Ci sono alcune risorse sul web. Piuttosto che fare un povero tentativo di consigliare qualcosa che non ho prima esperienza in, ti rimando ad un post passato:

C++ GDB Python Pretty Printing Tutorial?

0

quando si compila l'opzione -ggdb uso e vedere se funziona

http://sourceware.org/gdb/onlinedocs/gdb/Inline-Functions.html

Inlining è un'ottimizzazione che inserisce una copia del corpo della funzione direttamente in ogni sito di chiamata, invece di saltare a una routine condivisa. gdb mostra funzioni integrate come le funzioni non inline. Appaiono in backtraces. Puoi visualizzare i loro argomenti e le variabili locali, passarci sopra con il passo, saltare con il prossimo e scappare da loro con la fine. È possibile verificare se una funzione è stata sottolineata utilizzando il comando frame info.

Per gdb per il supporto delle funzioni inline, il compilatore deve registrare le informazioni sull'inlining nelle informazioni di debug - gcc utilizzando il formato nano 2 fa questo e anche molti altri compilatori. gdb supporta solo funzioni integrate quando si usa nano 2. Le versioni di gcc precedenti alla 4.1 non emettono due attributi obbligatori ('DW_AT_call_file' e 'DW_AT_call_line'); gdb non mostra chiamate di funzione con le versioni precedenti di gcc. Visualizza invece gli argomenti e le variabili locali delle funzioni integrate come variabili locali nel chiamante.

Il corpo di una funzione in linea è direttamente incluso nel sito di chiamata; a differenza di una funzione non inline, non ci sono istruzioni dedicate alla chiamata. gdb fa ancora finta che il sito di chiamata e l'inizio della funzione inline siano istruzioni diverse. Passando al sito di chiamata viene visualizzato il sito di chiamata, quindi viene nuovamente visualizzata la prima riga della funzione inline, anche se non vengono eseguite ulteriori istruzioni.

Ciò rende molto più chiaro il debug a livello di origine; puoi vedere sia il contesto della chiamata che l'effetto della chiamata. Il solo passaggio da una singola istruzione usando stepi o nexti non lo fa; i singoli passi dell'istruzione mostrano sempre il corpo in linea.

ci sono alcuni modi che gdb non pretende che le chiamate di funzione inline sono le stesse chiamate normali:

Impostazione punti di interruzione presso il sito di chiamata di una funzione inline non può funzionare, perché il sito chiamata non contiene alcun codice. gdb potrebbe spostare erroneamente il breakpoint sulla riga successiva della funzione di chiusura, dopo la chiamata. Questa limitazione verrà rimossa in una versione futura di gdb; fino a quel momento, impostare un punto di interruzione su una linea precedente o all'interno della funzione inline. gdb non è in grado di individuare il valore restituito delle chiamate in linea dopo aver utilizzato il comando finish.Questa è una limitazione delle informazioni di debug generate dal compilatore; dopo la fine, è possibile passare alla riga successiva e stampare una variabile in cui il programma ha memorizzato il valore restituito.

2

Prova questo:

di stampa (* obj.px) .i

codice completo è qui sotto:

(gdb) list 1,23 
1  #include <iostream> 
2  #include <boost/shared_ptr.hpp> 
3  #include <string> 
4 
5  class MyClass 
6  { 
7   public: 
8    MyClass() 
9     : name("Testing") 
10    { 
11     i=10; 
12    } 
13   private: 
14    int i; 
15    std::string name; 
16  }; 
17 
18 
19  int main(int argc, const char *argv[]) 
20  { 
21   boost::shared_ptr <MyClass> obj(new MyClass()); 
22   return 0; 
23  } 
(gdb) p obj 
$9 = {px = 0x602010, pn = {pi_ = 0x602060}} 
(gdb) p (*obj.px).i 
$10 = 10 
(gdb) p (*obj.px).name 
$11 = {static npos = 18446744073709551615, 
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x602048 "Testing"}}