Sprawdzanie zawartości standardowego kontenera (std :: map) za pomocą gdb

93

Przypuśćmy, że mamy coś takiego:

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}

Chciałbym móc sprawdzić zawartość mapy, na której działa program z gdb.
Jeśli spróbuję użyć operatora indeksu dolnego, otrzymam:

(gdb) p m[1]
Attempt to take address of value not located in memory.

Użycie metody wyszukiwania nie daje lepszych wyników:

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

Czy istnieje sposób, aby to osiągnąć?

Paolo Tedesco
źródło
Aby wydrukować wszystkie elementy bez obcinania dużych map: stackoverflow.com/questions/47743215/… Bardziej „Nie można ocenić funkcji może być wbudowane” skoncentrowane: stackoverflow.com/questions/40633787/ ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

35

Myślę, że nie ma, przynajmniej nie, jeśli twoje źródło jest zoptymalizowane itp. Jednak jest kilka makr dla gdb, które mogą sprawdzić dla ciebie kontenery STL:

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

Jednak nie używam tego, więc YMMV

jpalecek
źródło
1
Dzięki za link; jedyną rzeczą jest to, że makra są zależne od wersji bibliotek stl, czego wolałbym unikać. +1
Paolo Tedesco
Trochę frustrujące jest również to, że polecenia takie jak „plist foo std :: string” powodują błędy składniowe. Wygląda na to, że typ_wartości nie może zawierać żadnych znaków interpunkcyjnych.
Bklyn
2
Nie próbowałem, ale jeśli to działa tak samo jak reszta GDB, umieszczenie nazwy w postaci znaków interpunkcyjnych w pojedynczych cudzysłowach powinno to zrobić.
jpalecek
2
Uwaga: funkcjonalność std :: map w tych skryptach zakłada 32-bitowe typy wskaźników. Na komputerach 64-bitowych zamień „+ 4” na „+ 8” w całym pliku.
Kyle Simek
pvector nie jest zdefiniowany w moim gdb (wersja 7.5.91.20130417-cvs-ubuntu).
Jeff,
92

Istniejące odpowiedzi na to pytanie są bardzo nieaktualne. Dzięki najnowszym GCC i GDB to Just Works TM dzięki wbudowanej obsłudze Pythona w GDB 7.x i ładnym drukarkom libstdc ++, które są dostarczane z GCC.

Na przykład OP otrzymuję:

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

Jeśli to nie zadziała automatycznie, zobacz pierwszy punkt na stronie pomocy STL na wiki GDB.

Możesz napisać ładne drukarki Python dla własnych typów, zobacz Pretty Printing w podręczniku GDB.

Jonathan Wakely
źródło
2
Tak, ale inne pytania są zamykane jako ich duplikaty, więc chciałem, aby zawierały najnowsze informacje.
Jonathan Wakely
1
Używam GDB 7.2 i powyższe działa ... jeśli masz małą kolekcję. Nadal nie znalazłem sposobu, aby wydrukować powiedzmy element 1543 z wektora 4K, poza uciekaniem się do wykorzystania wewnętrznych struktur implementacji STL.
pavon
5
Tak, w GDB 7.2 i kompilatorze icpc pojawia się błąd Could not find operator[].
pavon
11
Niestety nie działa to tylko we wszystkich dystrybucjach. Nie jest instalowany domyślnie w Ubuntu 13.10 i pojawiają się problemy przy próbie instalacji ręcznie
nietaki
1
@razeh, Fedora, RHEL (i klony RHEL). Trwa naprawa, która sprawi, że drukarki będą działać również w dystrybucjach, w których GDB jest połączony z Pythonem 3
Jonathan Wakely,
25

Zawsze jest coś oczywistego: zdefiniuj własną funkcję testową ... Wywołaj ją z gdb. Na przykład:

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

I:

....
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) 
Panie Ree
źródło
16
tak długo, jak trwa proces. nie jest tak przydatny przy zrzutach pamięci.
sean riley
2
Jest to przydatna rada dotycząca ogólnego debugowania GDB, a nie tylko STL. Utrzymuję całą bibliotekę funkcji pomocniczych gdb dla wielu trudnych do odzyskania danych, np. Write_cuda_array_as_image (). Zauważ, że niektóre kompilatory usuwają wszystkie funkcje, które nie są wywoływane, więc wywołuję każdą funkcję pomocniczą po wyrażeniu „return 0;” w moim main. Również zadeklarowanie ich za pomocą zewnętrznego "C" ułatwia wywoływanie ich z gdb.
Kyle Simek
21

stl-views.gdbKiedyś najlepszą odpowiedź nie było, ale już nie.

To nie jest jeszcze zintegrowane z główną linią GDB, ale oto, co otrzymujesz, używając gałęzi `` 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
Zatrudniony Rosjanin
źródło
12

Spróbuj usunąć odniesienia do kontenerów STL: na tej stronie: http://www.yolinux.com/TUTORIALS/GDB-Commands.html

anand
źródło
To wygląda na biznes!
Richard Corden
W rzeczywistości są to te same makra, co w poprzedniej odpowiedzi :) Obawiam się, że nie ma prostszego rozwiązania.
Paolo Tedesco
Jakie jest polecenie? Udało ci się wyprowadzić nas poza miejsce z dużą ilością nieistotnych informacji. Nie interesuje mnie „Jak zacząć GDB” i inne.
jww
1

Powyższe odpowiedzi działają i są w porządku. Jeśli używasz stl-views.gdb, oto właściwy sposób przeglądania map i elementów w nim zawartych. Niech twoja mapa wygląda następująco: std::map<char, int> myMap;

(gdb) pmap myMap char int

tj. pmap <variable_name> <left_element_type> <right_element_type>zobaczyć elementy na mapie.

Mam nadzieję, że to pomoże.

Mazhar MIK
źródło
0

Możesz obejść drugi problem ( Cannot evaluate function -- may be inlined), upewniając się, że Twój kompilator używa informacji debugowania DWARF-2 (lub 3 lub 4) podczas kompilowania programu. DWARF-2 zawiera wbudowane informacje, więc powinieneś być w stanie użyć dowolnej z opisanych metod, aby uzyskać dostęp do elementów std::mapkontenera.

Aby skompilować z informacjami debugowania DWARF-2, dodaj -gdwarf-2flagę do polecenia kompilacji.

Dan
źródło
1
Um, wiedza, gdzie funkcja została wstawiona, nie umożliwia GDB oceny wywołań tej funkcji; GDB naprawdę potrzebuje dostępu do zewnętrznej kopii tej funkcji!
SamB