Подтвердить что ты не робот

Печать/отладка libС++ STL с XCode/LLDB

Я пытаюсь использовать LLDB в Xcode 8 для отладки очень простого STL. Раньше я мог печатать такой вектор:

p myvector[0]

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

error: Couldn't lookup symbols:
  __ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm

Вместо этого мне нужно набрать это:

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

Я попытался импортировать скрипты libcxx.py и unordered_multi.py из репозитория svn LLDB, но это ничего не меняет.

Кто-нибудь мог получить полезный вывод из LLDB с libС++??

4b9b3361

Ответ 1

[] - это оператор-оператор на std::vector, поэтому для распечатки требуемого выражения lldb должен будет иметь возможность вызвать метод []. Проблема здесь в том, что STL на OS X агрессивно относится к вложению всего, что может, и не тратить впустую пространство, производящее из линейных копий одни и те же функции. Это отлично подходит для оптимизированного кода, но не так хорошо подходит для отладки, потому что он оставляет отладчик без оператора [] для вызова. Это сообщение об ошибке, которое вы видите.

Если вы просто хотите увидеть элементы в этом векторе, вы можете использовать lldb "Форматы данных STL" , чтобы выполнить эту работу для вас. Они знают, как выкладываются большинство типов STL, и могут печатать элементы большинства типов контейнеров. Например:

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

а

(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)
}

Существует еще одна команда "фрейм-переменная, которая может проверять статические объекты и перехватывает данные. Он не может вызывать функции и выполнять другие более сложные задачи парсера выражения, но он знает, как использовать форматиры данных STL для извлечения отдельных элементов:

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

Вы даже можете использовать опцию frame var -L для поиска элементов вектора, а затем вы можете передать адрес, чтобы передать его другим функциям:

(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

Другой способ обойти это для отладки - если вы используете С++ 11 - это поставить:

template class std::vector<MyClass>

в вашем коде где-нибудь. Это даст указание компилятору испустить вне очереди копии всех функций шаблона для этой специализации. Это не большое общее решение, и вы хотите сделать это только для отладочных сборников, но это позволяет вам вызывать эти функции и использовать их в сложных выражениях.