2016-09-24 14 views
20

Próbuję użyć LLDB w Xcode 8 do debugowania bardzo podstawowego STL. Byłem w stanie wydrukować taki wektor:Drukowanie/debugowanie libC++ STL z XCode/LLDB

p myvector[0] 

, aby zobaczyć, co było w pierwszym indeksem wektorowym. Teraz, kiedy mam to zrobić, otrzymuję ten błąd:

error: Couldn't lookup symbols: 
    __ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm 

Zamiast tego muszę wpisać to:

p myvector.__begin_[0] in order to get any output. 

Próbowałem importowanie libcxx.py i skryptów unordered_multi.py z repozytorium svn LLDB ale to niczego nie zmienia.

Ktoś był w stanie uzyskać wszelkie przydatne wyniki z LLDB z libC++ ??

+0

Czy skompilowałeś informacje debugowania? Czy możesz zapewnić samodzielny reproduktor? – EricWF

+1

Oczywiście informacje debugowania są włączone. :) Oto głupi projekt, który może odtworzyć problem. Wystarczy ustawić punkt przerwania na linii std :: cout i uruchomić komendę lldb "p myVector [0]" po trafieniu. Otrzymasz błąd. Jeśli zrobisz "p myVector .__ begin_ [0]", to ładnie się wydrukuje. https://www.dropbox.com/s/ntjywxabxj3e4mc/Crap.zip?dl=0 – cjserio

Odpowiedz

47

[] to metoda operatora na std::vector, więc aby wydrukować żądane wyrażenie, lldb musiałoby wywołać metodę []. Problem polega na tym, że STL na OS X jest agresywny, jeśli chodzi o zaznaczanie wszystkiego, co może, i nie marnuje przestrzeni produkując kopie tych samych funkcji. To świetnie nadaje się do zoptymalizowanego kodu, ale nie jest tak dobre dla debugowania, ponieważ pozostawia debugger bez operatora do zadzwonienia. To jest komunikat o błędzie, który widzisz.

Jeśli chcesz zobaczyć elementy w tym wektorze, możesz użyć lldb "Formaterów danych STL", aby wykonać tę pracę za Ciebie. Wiedzą, jakie rodzaje STL są ułożone, i mogą drukować elementy większości typów kontenerów. Na przykład:

(lldb) expr my_vec[0] 
error: Couldn't lookup symbols: 
    __ZNSt3__16vectorI3FooNS_9allocatorIS1_EEEixEm 

ale:

(lldb) expr my_vec 
(std::__1::vector<Foo, std::__1::allocator<Foo> >) $0 = size=2 { 
    [0] = (var1 = 10, var2 = 20) 
    [1] = (var1 = 10, var2 = 20) 
} 

Istnieje również inne polecenie „zmienna rama” który może kontrolować obiekty statyczne oraz haki do formatujących danych. Nie można wywołać funkcje i robić inne bardziej złożone zadania parsera wyrażenie, ale nie wie, jak korzystać z formatek danych STL odzyskać poszczególne elementy:

(lldb) frame var my_vec[1] 
(Foo) my_vec[1] = (var1 = 10, var2 = 20) 

Można nawet użyć -L opcję poklatkowe VAR, aby zlokalizować elementy wektora, a następnie można oddać adres przekazać go do innych funkcji:

(lldb) frame var -L my_vec[1] 
0x0000000100100348: (Foo) my_vec[1] = { 
0x0000000100100348: var1 = 10 
0x000000010010034c: var2 = 20 
} 
(lldb) expr printf("%d\n", ((class Foo *) 0x0000000100100348)->var1) 
10 
(int) $3 = 3 

innym sposobem obejścia tego do debugowania - jeśli używasz C++ 11 - jest poprzez umieszczenie:

template class std::vector<MyClass> 

gdzieś w twoim kodzie. To instruuje kompilator, aby emitował kopie wszystkich funkcji szablonu dla tej specjalizacji poza linią. To nie jest świetne ogólne rozwiązanie, a ty chcesz to zrobić tylko dla kompilacji debugowania, ale pozwala ci wywoływać te funkcje i używać ich w złożonych wyrażeniach.

+1

Bardzo dokładna odpowiedź Jim, doceniam to! – cjserio

+0

Bookmarking this. Bardzo pomocne! –

+0

Widzę to samo zachowanie w systemie Linux (Ubuntu 16.10) z clang/lldb 3.9. Ale gcc/gdb nie ma problemu z '(gdb) p my_vec [0]'. Zastanawiam się, co robią inaczej. –