Проверка содержимого стандартного контейнера (std :: map) с помощью gdb

Предположим, что есть что-то вроде этого:

#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

Есть ли способ добиться этого?

Чтобы напечатать все элементы без усечения больших карт: stackoverflow.com/questions/47743215/… Больше сфокусировано на «Невозможно оценить функцию, возможно, встроено»: stackoverflow.com/questions/40633787/…

Ciro Santilli新疆棉花TRUMP BAN BAD 24.09.2020 15:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
95
1
95 420
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Я думаю, что нет, по крайней мере, если ваш источник оптимизирован и т. д. Однако есть несколько макросов для gdb, которые могут проверять контейнеры STL для вас:

http://sourceware.org/ml/gdb/2008-02/msg00064.html

Однако я этим не пользуюсь, поэтому YMMV

Спасибо за ссылку; единственное, что макросы зависят от версии библиотеки stl, чего я бы предпочел избежать. +1

Paolo Tedesco 09.01.2009 13:41

Также немного расстраивает то, что команды типа "plist foo std :: string" дают синтаксические ошибки. Похоже, что value_type не может содержать знаков препинания.

Bklyn 10.01.2009 00:49

Я не пробовал, но если это работает так же, как и остальная часть GDB, следует заключить имя с пунктуацией в одинарные кавычки.

jpalecek 10.01.2009 02:35

Примечание. Функциональность std :: map в этих сценариях предполагает 32-разрядные типы указателей. Для 64-битных машин замените "+ 4" на "+ 8" везде в файле.

Kyle Simek 21.05.2012 00:22

pvector не определен в моем gdb (версия 7.5.91.20130417-cvs-ubuntu).

Jeff 22.07.2013 20:21

Попробуйте отменить ссылку на контейнеры STL: на этой странице: http://www.yolinux.com/TUTORIALS/GDB-Commands.html

Похоже, это бизнес!

Richard Corden 09.01.2009 17:42

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

Paolo Tedesco 09.01.2009 17:59

Что это за команда? Вам удалось запустить нас за пределы сайта с огромным количеством нерелевантной информации. Меня не интересует "Как запустить GDB" и прочее.

jww 10.04.2016 04:30

Всегда есть очевидное: определите свою собственную тестовую функцию ... Вызовите ее из 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) 

пока процесс запущен. не так полезно для дампов ядра.

sean riley 14.08.2009 04:15

Это полезный совет по отладке GDB в целом, а не только с помощью STL. Я храню целую библиотеку вспомогательных функций gdb для большого количества трудно извлекаемых данных, например write_cuda_array_as_image (). Обратите внимание, что некоторые компиляторы удаляют все функции, которые не были вызваны, поэтому я помещаю вызов каждой вспомогательной функции после моей main «return 0;». Кроме того, объявление их с помощью extern «C» упрощает их вызов из gdb.

Kyle Simek 21.05.2012 00:30

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 действительно нужен доступ к внешней копии функции!

SamB 03.02.2015 06:09

Существующие ответы на этот вопрос очень устарели. С недавними версиями 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.

Спасибо за ответ ... на самом деле сам вопрос уже устарел :)

Paolo Tedesco 11.03.2013 11:53

Да, но другие вопросы закрываются как дубликаты, поэтому я хотел, чтобы у них была свежая информация.

Jonathan Wakely 11.03.2013 13:12

Я использую GDB 7.2, и все вышесказанное работает ... если у вас небольшая коллекция. Я до сих пор не нашел способа распечатать, скажем, элемент 1543 из вектора 4K, кроме как использовать внутренние структуры реализации STL.

pavon 09.10.2013 22:35

@pavon, а ты print vec[1543] пробовал? который отлично работает у меня с GDB 7.6

Jonathan Wakely 10.10.2013 02:42

Да, в GDB 7.2 и компиляторе icpc я получаю ошибку Could not find operator[].

pavon 10.10.2013 03:19

К сожалению, он не работает во всех дистрибутивах. Он не установлен по умолчанию в Ubuntu 13.10 и есть проблемы при попытке установить вручную

nietaki 10.01.2014 02:18

Это показывает всю карту. ОП спросил, как показать конкретный элемент карты.

user570500 24.04.2014 17:43

@ user570500, это один из способов интерпретации. OP спрашивает: «Я хотел бы иметь возможность проверить содержимое карты, запускающей программу из gdb. [...] Есть ли способ сделать это?» Мой ответ показывает способ проверить содержимое.

Jonathan Wakely 25.04.2014 22:55

@JonathanWakely Какой дистрибутив вы используете, где он просто работает?

razeh 20.06.2014 19:02

@razeh, Fedora, RHEL (и клоны RHEL). Выполняется исправление, чтобы принтеры также работали в дистрибутивах, где GDB связан с Python 3.

Jonathan Wakely 10.07.2014 20:33

Исходный код GCC был исправлен для работы с Python3, поэтому скоро он должен работать в Ubuntu и Debian.

Jonathan Wakely 29.08.2014 15:52

Для этого нужно определение «недавний» .... это не очень полезно для людей, застрявших на «не недавнем», если они не знают, что им нужно обновить.

UKMonkey 22.11.2018 21:09

@UKMonkey, учитывая, что ответ старше пяти лет, «что-то менее шести лет» было бы довольно очевидным (и консервативным) предположением. Похоже, принтеры libstdC++ были добавлены для GCC 4.5.0, выпущенного в 2010 году. Некоторые дистрибутивы перенесли их в GCC 4.4, а может быть и раньше.

Jonathan Wakely 22.11.2018 22:56

@JonathanWakely :) Я не согласен ... но gdb, с которым я застрял, "действительно довольно старый" (более 8 лет), поэтому я сделал свой комментарий, и, похоже, он не работает ( тм). Печальные времена - я думаю, потребовалось больше поиска в Google!

UKMonkey 23.11.2018 12:02

@UKMonkey, если вы спрашиваете о GDB, в ответе уже написано GDB 7.x (и так было с 2013 года).

Jonathan Wakely 23.11.2018 13:57

И ссылка «Поддержка STL», которую я дал в ответе, гласит: «GDB 7.0 будет включать поддержку написания симпатичных принтеров на Python».

Jonathan Wakely 23.11.2018 14:17

Можно ли распечатать реализацию / тело std::function с помощью GDB?

skytree 09.03.2019 13:45

@skytree, который действительно должен быть отдельным вопросом или в списке рассылки gcc-help, а не как комментарий к вопросу о std :: map. Ответ - нет, но кто-нибудь мог бы написать для него принтер.

Jonathan Wakely 09.03.2019 14:02

@JonathanWakely Спасибо. Не могли бы вы предложить мне ссылку на этот принтер или просто связанные сообщения?

skytree 09.03.2019 14:21

Ответы выше работают и в порядке. Если вы используете stl-views.gdb, вот правильный способ просмотра карт и элементов внутри него. Пусть ваша карта будет такой: std::map<char, int> myMap;

(gdb) pmap myMap char int

то есть pmap <variable_name> <left_element_type> <right_element_type>, чтобы увидеть элементы на карте.

Надеюсь, это поможет.

Другие вопросы по теме