2014-04-01 16 views
9

std::unique_ptr są ładne, ale uważam je za mniej wygodne podczas debugowania w DDD lub gdb.Jak debugować kod C++ 11 za pomocą unique_ptr w DDD (lub gdb)?

Używam ładnych drukarek gdb, które są częścią gcc (np. /usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py). To jest wielka wygrana dla czytelności, na przykład:

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

Jednak dereferencji wskaźnik nie działa:

$ print *pTest 
Could not find operator*. 

Kiedy trzeba uzyskać dostęp do wartości, muszę ręcznie skopiować wskaźnika, a także oddanych do odpowiedniego typu, na przykład:

print *((MyType*) 0x2cef0a0) 

Jeśli proces nadal działa, ta wersja działa (wciąż brzydki, ale lepiej):

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

Bezpośrednie podejście do Display *pTest w DDD również nie działa. Wynika to wyłącznie w następujący błąd:

<error: Could not find operator*.> 

Czy istnieje sposób do debugowania kodu z unique_ptr w DDD C++ 11 (bez przerywania przepływu pracy tak jak ja z moimi uciążliwych obejściach)?


Nie boję się używać poleceń gdb, ale integracja DDD byłaby plusem. Na przykład następujące wskaźniki w strukturach danych po dwukrotnym kliknięciu na nich są często szybsze niż pisanie na klawiaturze.

Próbowałem już upuścić ładną drukarkę, ale nie jest ona również optymalna. Najlepsze, co mogę wymyślić jest następujący:

print pTest._M_t->_M_head_impl 
+0

może brzmieć jak głupie pytanie, ale czy trzeba zbudować Kompilator gcc na swoim pudełku od zera? A może była to aktualizacja RPM? Ostatnio miałem problem z gdb podczas próby debugowania kodu C++ 11, i odkryłem, że nie skompilowałem ponownie gdb. Jestem prawie pewien, że tak nie jest, ale pomyślałem, że warto o to zapytać. – Welshboy

+0

@Welshboy Używam obecnie oficjalnego gcc 4.8.2 (20140206) i gdb 7.7 z Arch Linux. –

+1

Możesz spróbować tego: http://stackoverflow.com/questions/322322/displaying-dereferenced-stl-iterators-in-gdb, a zwłaszcza zajrzyj do pliku gdbinit. Wygląda na to, że istnieje wiele niestandardowych rzeczy, które możesz zrobić w gdb. Powodzenia. – Ben

Odpowiedz

7

Ten problem jest rzeczywiście niezwiązane z C++ 11, unique_ptr lub drukowania ładna. Problem polega na tym, że gcc nie emituje kodu dla std :: unique_ptr :: operator *, który mógłby zostać wywołany przez gdb do dereferencji unique_ptr. Jeśli na przykład dodasz kod *pTest;, gdb wykona dereferencję.

Podobny problem opisano w poście SO nr How to `print`/evaluate c++ template functions in gdb. Prawie ten sam problem opisano dla auto_ptr pod adresem https://sourceware.org/ml/archer/2012-q1/msg00003.html. Jeśli dobrze zrozumiem wątek, jednym z rozwiązań byłoby łatanie ładnej drukarki, a także drukowanie wskaźnika dereferencji podczas drukowania unique_ptr. Raport błędu gdb można znaleźć pod adresem http://sourceware.org/bugzilla/show_bug.cgi?id=12937.

Witryna gdb pod adresem https://sourceware.org/gdb/wiki/STLSupport opisuje więcej ładnych rozwiązań do drukowania, które mogą mieć inne obejścia.

Edit: Bardziej eleganckie rozwiązanie zmusza kompilator emituje kod dla wszystkich szablonów członkowskich, w tym operatora * jest jawnie instancję klasy:

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

gdzie powinienem zdefiniować to jawne tworzenie? – q0987

+0

Z technicznego punktu widzenia dokładnie w jednej z jednostek tłumaczeniowych ("plik cpp") po uwzględnieniu nagłówka 'memory' i po deklaracji' MyType' (lub odpowiedniego uwzględnienia) - patrz http: //en.cppreference .com/w/cpp/language/class_template # Explicit_instantiation – user1225999