Проверка содержимого стандартного контейнера (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.
Использование метода find не дает лучших результатов:
(gdb) p m.find(1)
Cannot evaluate function -- may be inlined
Есть ли способ добиться этого?
Решение
Я думаю, что нет, по крайней мере, если ваш источник оптимизирован и т. д. Однако, есть некоторые макросы для GDB, которые могут проверять контейнеры STL для вас:
http://sourceware.org/ml/gdb/2008-02/ msg00064.html р>
Однако я этим не пользуюсь, поэтому YMMV
Другие советы
Существующие ответы на этот вопрос очень устарели. С недавним 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.
Всегда очевидно:Определите свою собственную тестовую функцию...Вызовите его из 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)
Раньше 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
Попробуйте разыменовать контейнеры STL: на этой странице: http: //www.yolinux .com / учебники / GDB-Commands.html р>
Вы можете обойти вторую проблему (Cannot evaluate function -- may be inlined
), убедившись, что ваш компилятор использует отладочную информацию DWARF-2 (или 3 или 4) при компиляции вашей программы. DWARF-2 содержит встроенную информацию, поэтому вы должны использовать любой из описанных вами методов для доступа к элементам вашего std::map
контейнера.
Чтобы скомпилировать с отладочной информацией DWARF-2, добавьте флаг -gdwarf-2
в команду компиляции.
Ответы выше работают и все в порядке.Если вы используете stl-views.gdb, вот правильный способ просмотра карт и элементов внутри него.Пусть ваша карта выглядит следующим образом: std::map<char, int> myMap;
(gdb) pmap myMap char int
то есть pmap <variable_name> <left_element_type> <right_element_type>
чтобы увидеть элементы на карте.
Надеюсь, это поможет.