2014-04-01 10 views
9

std::unique_ptr sind nett, aber ich finde sie weniger bequem beim Debuggen in DDD oder gdb.Wie Debuggen von C++ 11-Code mit Unique_ptr in DDD (oder Gdb)?

Ich verwende die gdb hübschen Drucker, die Teil von gcc sind (z. B. /usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py). Das ist ein großer Gewinn für die Lesbarkeit, zum Beispiel:

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

jedoch nicht den Zeiger Dereferenzierung nicht:

$ print *pTest 
Could not find operator*. 

Wenn ich den Wert zugreifen müssen, muss ich manuell den Zeiger kopieren und warf es auf den richtigen Typ, zum Beispiel:

print *((MyType*) 0x2cef0a0) 

Wenn der Prozess noch läuft, ist diese Version funktioniert (noch hässlich, aber besser):

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

Der direkte Ansatz zu Display *pTest in DDD funktioniert auch nicht. Es ergibt sich nur in dem folgenden Fehler:

<error: Could not find operator*.> 

Gibt es eine Möglichkeit C++ 11-Code mit unique_ptr in DDD debuggen (ohne den Workflow zu brechen, wie ich mit meiner umständlichen Behelfslösungen tun)?


Ich habe keine Angst, Gdb-Befehle zu verwenden, aber DDD-Integration wäre ein Pluspunkt. Zum Beispiel ist das Verfolgen von Zeigern in Datenstrukturen durch einfaches Doppelklicken doppelt schneller als Tippen.

Ich habe schon versucht, den hübschen Drucker fallen zu lassen, aber es ist auch nicht optimal. Das Beste, was ich tun konnte, ist die folgende:

print pTest._M_t->_M_head_impl 
+0

wie eine dumme Frage klingen, aber haben Sie die bauen müssen GCC-Compiler auf Ihrer Box von Grund auf neu? Oder war es ein RPM-Update? Ich hatte kürzlich ein Problem mit gdb, als ich versuchte, etwas C++ 11-Code zu debuggen, und fand heraus, dass ich gdb nicht neu kompiliert hatte. Ich bin mir ziemlich sicher, dass das hier nicht der Fall ist, aber ich dachte, dass es sich lohnt, danach zu fragen. – Welshboy

+0

@Welshboy Ich verwende derzeit die offizielle gcc 4.8.2 (20140206) und gdb 7.7 von Arch Linux. –

+1

Sie könnten dies versuchen: http://stackoverflow.com/questions/322322/displaying-dereferenced-stl-iterators-in-gdb und insbesondere eine gdbinit-Datei ansehen. Es sieht so aus, als gäbe es viele benutzerdefinierte Dinge, die gdb machen kann. Viel Glück. – Ben

Antwort

7

Dieses Problem ist eigentlich nicht im Zusammenhang mit C++ 11, unique_ptr oder ziemlich Druck. Das Problem ist, dass gcc keinen Code für std :: unique_ptr :: operator * ausgibt, der von gdb aufgerufen werden könnte, um den unique_ptr zu dereferenzieren. Wenn Sie beispielsweise Ihrem Code *pTest; hinzufügen, führt gdb die Dereferenzierung durch.

Ein ähnliches Problem ist in der SO Post How to `print`/evaluate c++ template functions in gdb beschrieben. Fast das gleiche Problem wird für ein auto_ptr bei https://sourceware.org/ml/archer/2012-q1/msg00003.html beschrieben. Wenn ich den Thread richtig verstehe, wäre eine Umgehungsmöglichkeit, den hübschen Drucker zu patchen und auch den dereferenzierten Zeiger auszudrucken, wenn der unique_ptr gedruckt wird. Ein gdb Fehlerbericht kann unter http://sourceware.org/bugzilla/show_bug.cgi?id=12937 gefunden werden.

Das gdb-Wiki unter https://sourceware.org/gdb/wiki/STLSupport beschreibt schönere Drucklösungen, die andere Problemumgehungen haben könnten.

Edit: Eine elegantere Lösung den Compiler zwingen zu emittieren Code für alle Mitgliedsvorlagen einschließlich Operator * wird explizit die Klasse instanziiert:

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

Wo sollte ich diese explizite Instanziierung definieren? – q0987

+0

Aus technischer Sicht in genau einer Ihrer Übersetzungseinheiten ("cpp-Datei") nach dem Einschließen des 'memory'-Headers und nach der Deklaration von' MyType' (oder dem entsprechenden Include) - siehe http: //en.cppreference .com/w/cpp/Sprache/Klasse_Template # Explizite_Instantiation – user1225999