Проверка содержимого стандартного контейнера (std :: map) с помощью gdb - PullRequest
81 голосов
/ 09 января 2009

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

#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.

Использование метода find не дает лучших результатов:

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined

Есть ли способ сделать это?

Ответы [ 7 ]

81 голосов
/ 11 марта 2013

Существующие ответы на этот вопрос очень устарели. Благодаря недавним GCC и GDB он просто работает TM благодаря встроенной поддержке Python в GDB 7.x и симпатичным принтерам libstdc ++, которые поставляются с GCC.

Для примера ОП я получаю:

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}

Если это не сработает автоматически, вы увидите первую точку на странице Поддержка STL вики GDB.

Вы также можете написать красивые принтеры Python для своих собственных типов, см. Pretty Printing в руководстве по GDB.

32 голосов
/ 09 января 2009

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

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

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

21 голосов
/ 10 января 2009

Всегда очевидно: определите свою собственную тестовую функцию ... Вызовите ее из GDB E.g.:

#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) 
20 голосов
/ 12 января 2009

Раньше был лучший ответ stl-views.gdb, но не больше.

Это еще не интегрировано в магистраль GDB, но вот что вы получите, используя 'archer-tromey-python' branch :

(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
12 голосов
/ 09 января 2009

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

0 голосов
/ 08 января 2019

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

(gdb) pmap myMap char int

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

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

0 голосов
/ 04 февраля 2013

Вы можете обойти вторую проблему (Cannot evaluate function -- may be inlined), убедившись, что ваш компилятор использует отладочную информацию DWARF-2 (или 3 или 4) при компиляции вашей программы. DWARF-2 содержит встроенную информацию, поэтому вы можете использовать любой из описанных вами методов для доступа к элементам вашего std::map контейнера.

Чтобы скомпилировать с отладочной информацией DWARF-2, добавьте флаг -gdwarf-2 в команду компиляции.

...