2014-04-01 4 views
9

std::unique_ptr хороши, но я считаю их менее удобными при отладке в DDD или gdb.Как отлаживать код C++ 11 с unique_ptr в DDD (или gdb)?

Я использую красивые принтеры gdb, которые являются частью gcc (например, /usr/share/gcc-4.8.2/python/libstdcxx/v6/printers.py). Это большая победа для читаемости, например:

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

Однако разыменования указателя не работает:

$ print *pTest 
Could not find operator*. 

Когда мне нужно получить доступ к значению, я должен вручную скопировать указатель и привести его к правильному типу, например:

print *((MyType*) 0x2cef0a0) 

Если процесс все еще работает, эта версия работает (еще некрасиво, но лучше):

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

Простой подход к Display *pTest в DDD также не работает. Это приводит только к следующей ошибке:

<error: Could not find operator*.> 

Есть ли способ отладки C++ 11 кода с unique_ptr в DDD (без нарушения рабочего процесса, как я делаю со своим громоздкими обходными)?

Я не боюсь использовать команды gdb, но интеграция с DDD будет плюсом. Например, следующие указатели в структурах данных путем двойного щелчка по ним часто бывают быстрее, чем ввод.

Я уже пытался сбросить красивый принтер, но он также не оптимален. Самое лучшее, что я мог придумать следующий:

print pTest._M_t->_M_head_impl 
+0

может звучать как немой вопрос, но вы должны построить gcc на вашем ящике с нуля? Или это обновление RPM? Недавно у меня возникла проблема с gdb при попытке отладки кода C++ 11, и я обнаружил, что не перекомпилировал gdb. Я почти уверен, что здесь дело не в этом, но я подумал, что это может стоить того. – Welshboy

+0

@Welshboy В настоящее время я использую официальный gcc 4.8.2 (20140206) и gdb 7.7 из Arch Linux. –

+1

Вы можете попробовать следующее: http://stackoverflow.com/questions/322322/displaying-dereferenced-stl-iterators-in-gdb и, в частности, посмотреть файл gdbinit. Похоже, есть много особых вещей, которые вы можете сделать gdb. Удачи. – Ben

ответ

7

Эта проблема на самом деле не связано с C++ 11, unique_ptr или симпатичной печати. Проблема в том, что gcc не выделяет код для std :: unique_ptr :: operator *, который может быть вызван gdb для разыменования unique_ptr. Если вы, например, добавите *pTest; в свой код, тогда gdb выполняет разыменование.

Аналогичная проблема описана в сообщении SO How to `print`/evaluate c++ template functions in gdb. Почти такая же проблема описана для auto_ptr на https://sourceware.org/ml/archer/2012-q1/msg00003.html. Если я правильно понял поток, одним из способов было бы исправление красивого принтера, а также распечатка указателя разыменования при печати unique_ptr. Отчет об ошибке gdb можно найти по адресу http://sourceware.org/bugzilla/show_bug.cgi?id=12937.

Вики-страница gdb на https://sourceware.org/gdb/wiki/STLSupport описывает более красивые решения для печати, которые могут иметь другие обходные пути.

Edit: более элегантное решение заставляет компилятор создать код для всех шаблонов членов, включая оператор * является явно экземпляром класса:

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

Где я должен определить это явное создание? – q0987

+0

С технической точки зрения точно в одном из ваших блоков перевода («cpp-файл») после включения заголовка 'memory' и после объявления' MyType' (или соответствующих включений) - см. Http: //en.cppreference .com/ж/CPP/язык/class_template # Explicit_instantiation – user1225999

 Смежные вопросы

  • Нет связанных вопросов^_^