2013-07-23 8 views
18

Es folgt mein Quellcode:Untersuchen Schub shared_ptr mit 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; 
} 

I obj in gdb untersuchen möchten, und den Wert der Membervariable i anzuzeigen. Diese

ist das, was ich bei Normaldruck erhalten:

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

ich die Spitze in this link erwähnt versucht, aber nicht funktioniert.

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

Gibt es einen anderen Weg? gdb-Version ist 7.0.1.

+0

Ein weiterer guter alter Freund Ebene printf ist:) –

+1

@ Anand Rathi ..., ja, aber ich wollte nur wissen, ob das mit gdb möglich ist. –

Antwort

28

Bekam es.!

(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

Das ist das nützlichste was ich den ganzen Tag gesehen habe !!! Danke vielmals. Ich wusste nicht, dass ich den Zeiger auf diese Weise dereferenzieren könnte. :-) – kmort

+3

Das funktioniert nicht für mich. "p obj" gibt '$ 2 = std :: shared_ptr (count 2, schwach 1) 0x639268', und" p obj.px "gibt' Es gibt kein Mitglied oder Methode mit dem Namen px'. Ich habe auch "p * obj" versucht, aber keine Freude: 'Konnte Operator * nicht finden –

0

Dies wird schwer zu beantworten sein. GDB 7.x hat Python-Skriptunterstützung hinzugefügt. Es gibt einige Ressourcen im Internet. Anstatt einen schlechten Versuch zu machen, sich auf etwas zu rate ich erste Erfahrungen nicht in haben, werde ich Sie auf ein vergangenes Post verweisen:

C++ GDB Python Pretty Printing Tutorial?

0

Wenn Sie verwenden -ggdb Option kompilieren und sehen, ob das funktioniert

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

Inlining ist eine Optimierung, die direkt an jedem Anruf Ort, anstatt springen zu einer gemeinsamen Routine eine Kopie des Funktionskörpers einfügt. gdb zeigt inlined Funktionen genau wie nicht-inlined Funktionen an. Sie erscheinen in Rückverfolgungen. Sie können ihre Argumente und lokalen Variablen anzeigen, mit ihnen in Schritt gehen, sie mit dem nächsten überspringen und mit dem Ende davon entkommen. Mit dem Befehl info frame können Sie prüfen, ob eine Funktion inline war.

Um inlineed Funktionen zu unterstützen, muss der Compiler Informationen über Inlining in den Debug-Informationen aufzeichnen - gcc im dwarf 2 Format tut dies, und einige andere Compiler machen das auch. gdb unterstützt nur inlined Funktionen, wenn Sie Zwerg 2 verwenden. Versionen von gcc vor 4.1 geben nicht zwei erforderliche Attribute aus ('DW_AT_call_file' und 'DW_AT_call_line'); gdb zeigt inlined Funktionsaufrufe mit früheren Versionen von gcc nicht an. Stattdessen werden die Argumente und lokalen Variablen von Inlined-Funktionen als lokale Variablen im Aufrufer angezeigt.

Der Körper einer Inlinefunktion ist direkt an seiner Aufrufstelle enthalten; Im Gegensatz zu einer nicht-inlined-Funktion gibt es keine Anweisungen für den Anruf. gdb gibt weiterhin vor, dass die Aufruf-Site und der Anfang der Inlined-Funktion unterschiedliche Anweisungen sind. Wenn Sie zur Aufruf-Site wechseln, wird die Aufruf-Site angezeigt und dann wird wieder die erste Zeile der Inline-Funktion angezeigt, obwohl keine zusätzlichen Anweisungen ausgeführt werden.

Dies macht Source-Level-Debugging viel klarer; Sie können sowohl den Kontext des Anrufs als auch die Auswirkung des Anrufs sehen. Nur durch eine einzige Anweisung mit stepi oder nexti zu gehen, tut dies nicht; einzelne Instruktionsschritte zeigen immer den Inline-Körper an.

Es gibt einige Möglichkeiten, die gdb erhebt nicht den Anspruch, dass inlined Funktion ruft die gleiche wie normale Anrufe sind:

Stützpunkte an der Aufrufstelle einer inlined Funktion einstellen kann nicht funktionieren, da der Aufruf-Website enthält keine Code. gdb kann den Haltepunkt nach dem Aufruf falsch in die nächste Zeile der umschließenden Funktion verschieben. Diese Einschränkung wird in einer zukünftigen Version von gdb entfernt. Bis dahin setzen Sie stattdessen einen Breakpoint auf eine frühere Zeile oder innerhalb der Inlined-Funktion. gdb kann den Rückgabewert von inlined-Aufrufen nach dem Befehl finish nicht finden.Dies ist eine Einschränkung der Compiler-generierten Debuginformationen; Danach können Sie zur nächsten Zeile springen und eine Variable ausgeben, in der Ihr Programm den Rückgabewert gespeichert hat.

2

Try this:

print (* obj.px) .i

vollständige Code ist unten:

(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"}}