Предположим, что есть что-то вроде этого:
#include <map>
int main(){
std::map<int,int> m;
m[1] = 2;
m[2] = 4;
return 0;
}
Я хотел бы иметь возможность проверить содержимое карты, запустив программу из gdb.
Если я попробую использовать оператор индекса, я получу:
(gdb) p m[1]
Attempt to take address of value not located in memory.
Использование метода поиска не дает лучших результатов:
(gdb) p m.find(1)
Cannot evaluate function -- may be inlined
Есть ли способ добиться этого?





Я думаю, что нет, по крайней мере, если ваш источник оптимизирован и т. д. Однако есть несколько макросов для gdb, которые могут проверять контейнеры STL для вас:
http://sourceware.org/ml/gdb/2008-02/msg00064.html
Однако я этим не пользуюсь, поэтому YMMV
Спасибо за ссылку; единственное, что макросы зависят от версии библиотеки stl, чего я бы предпочел избежать. +1
Также немного расстраивает то, что команды типа "plist foo std :: string" дают синтаксические ошибки. Похоже, что value_type не может содержать знаков препинания.
Я не пробовал, но если это работает так же, как и остальная часть GDB, следует заключить имя с пунктуацией в одинарные кавычки.
Примечание. Функциональность std :: map в этих сценариях предполагает 32-разрядные типы указателей. Для 64-битных машин замените "+ 4" на "+ 8" везде в файле.
pvector не определен в моем gdb (версия 7.5.91.20130417-cvs-ubuntu).
Попробуйте отменить ссылку на контейнеры STL: на этой странице: http://www.yolinux.com/TUTORIALS/GDB-Commands.html
Похоже, это бизнес!
На самом деле это те же макросы, что и в предыдущем ответе :) Боюсь, что нет более простого решения.
Что это за команда? Вам удалось запустить нас за пределы сайта с огромным количеством нерелевантной информации. Меня не интересует "Как запустить GDB" и прочее.
Всегда есть очевидное: определите свою собственную тестовую функцию ... Вызовите ее из gdb. Например.:
#define SHOW(X) cout << # X " = " << (X) << endl
void testPrint( map<int,int> & m, int i )
{
SHOW( m[i] );
SHOW( m.find(i)->first );
}
int
main()
{
std::map<int,int> m;
m[1] = 2;
m[2] = 4;
return 0; // Line 15.
}
А также:
....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD
Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb)
пока процесс запущен. не так полезно для дампов ядра.
Это полезный совет по отладке GDB в целом, а не только с помощью STL. Я храню целую библиотеку вспомогательных функций gdb для большого количества трудно извлекаемых данных, например write_cuda_array_as_image (). Обратите внимание, что некоторые компиляторы удаляют все функции, которые не были вызваны, поэтому я помещаю вызов каждой вспомогательной функции после моей main «return 0;». Кроме того, объявление их с помощью extern «C» упрощает их вызов из gdb.
stl-views.gdb раньше был лучшим ответом, но теперь это не так.
Это еще не интегрировано в основную версию GDB, но вот что вы получаете, используя ветка 'archer-tromey-python':
(gdb) list
1 #include <map>
2 int main(){
3 std::map<int,int> m;
4 m[1] = 2;
5 m[2] = 4;
6 return 0;
7 }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run
Breakpoint 1, main () at map.cc:6
6 return 0;
(gdb) print m
$1 = std::map with 2 elements = {
[1] = 2,
[2] = 4
}
(gdb) quit
Вы можете обойти вторую проблему (Cannot evaluate function -- may be inlined), убедившись, что ваш компилятор использует отладочную информацию DWARF-2 (или 3 или 4) при компиляции вашей программы. DWARF-2 включает в себя встраиваемую информацию, поэтому вы должны иметь возможность использовать любой из описанных вами методов для доступа к элементам вашего контейнера std::map.
Для компиляции с использованием отладочной информации DWARF-2 добавьте флаг -gdwarf-2 в свою команду компиляции.
Гм, знание того, где была встроена функция, не позволяет GDB оценивать вызовы этой функции; GDB действительно нужен доступ к внешней копии функции!
Существующие ответы на этот вопрос очень устарели. С недавними версиями GCC и GDB он Just WorksTM благодаря встроенной поддержке Python в GDB 7.x и симпатичным принтерам libstdC++, которые поставляются с GCC.
Для примера OP я получаю:
(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}
Если это не сработает автоматически, вы увидите первый пункт на странице Поддержка STL вики GDB.
Вы также можете написать симпатичные принтеры Python для ваших собственных типов, см. Симпатичная печать в руководстве GDB.
Спасибо за ответ ... на самом деле сам вопрос уже устарел :)
Да, но другие вопросы закрываются как дубликаты, поэтому я хотел, чтобы у них была свежая информация.
Я использую GDB 7.2, и все вышесказанное работает ... если у вас небольшая коллекция. Я до сих пор не нашел способа распечатать, скажем, элемент 1543 из вектора 4K, кроме как использовать внутренние структуры реализации STL.
@pavon, а ты print vec[1543] пробовал? который отлично работает у меня с GDB 7.6
Да, в GDB 7.2 и компиляторе icpc я получаю ошибку Could not find operator[].
К сожалению, он не работает во всех дистрибутивах. Он не установлен по умолчанию в Ubuntu 13.10 и есть проблемы при попытке установить вручную
Это показывает всю карту. ОП спросил, как показать конкретный элемент карты.
@ user570500, это один из способов интерпретации. OP спрашивает: «Я хотел бы иметь возможность проверить содержимое карты, запускающей программу из gdb. [...] Есть ли способ сделать это?» Мой ответ показывает способ проверить содержимое.
@JonathanWakely Какой дистрибутив вы используете, где он просто работает?
@razeh, Fedora, RHEL (и клоны RHEL). Выполняется исправление, чтобы принтеры также работали в дистрибутивах, где GDB связан с Python 3.
Исходный код GCC был исправлен для работы с Python3, поэтому скоро он должен работать в Ubuntu и Debian.
Для этого нужно определение «недавний» .... это не очень полезно для людей, застрявших на «не недавнем», если они не знают, что им нужно обновить.
@UKMonkey, учитывая, что ответ старше пяти лет, «что-то менее шести лет» было бы довольно очевидным (и консервативным) предположением. Похоже, принтеры libstdC++ были добавлены для GCC 4.5.0, выпущенного в 2010 году. Некоторые дистрибутивы перенесли их в GCC 4.4, а может быть и раньше.
@JonathanWakely :) Я не согласен ... но gdb, с которым я застрял, "действительно довольно старый" (более 8 лет), поэтому я сделал свой комментарий, и, похоже, он не работает ( тм). Печальные времена - я думаю, потребовалось больше поиска в Google!
@UKMonkey, если вы спрашиваете о GDB, в ответе уже написано GDB 7.x (и так было с 2013 года).
И ссылка «Поддержка STL», которую я дал в ответе, гласит: «GDB 7.0 будет включать поддержку написания симпатичных принтеров на Python».
Можно ли распечатать реализацию / тело std::function с помощью GDB?
@skytree, который действительно должен быть отдельным вопросом или в списке рассылки gcc-help, а не как комментарий к вопросу о std :: map. Ответ - нет, но кто-нибудь мог бы написать для него принтер.
@JonathanWakely Спасибо. Не могли бы вы предложить мне ссылку на этот принтер или просто связанные сообщения?
Ответы выше работают и в порядке. Если вы используете stl-views.gdb, вот правильный способ просмотра карт и элементов внутри него.
Пусть ваша карта будет такой:
std::map<char, int> myMap;
(gdb) pmap myMap char int
то есть pmap <variable_name> <left_element_type> <right_element_type>, чтобы увидеть элементы на карте.
Надеюсь, это поможет.
Чтобы напечатать все элементы без усечения больших карт: stackoverflow.com/questions/47743215/… Больше сфокусировано на «Невозможно оценить функцию, возможно, встроено»: stackoverflow.com/questions/40633787/…