Печать / отладка libc++ 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 скрипты из репозитория lldb svn, но это, похоже, ничего не меняет.
кто-нибудь смог получить любой полезный вывод из LLDB с libc++??
2 ответов
[]
- это метод оператора std::vector
, поэтому для печати выражения, которое вы хотите, lldb должен иметь возможность вызывать []
метод. Проблема здесь в том, что STL на OS X агрессивен в отношении вставки всего, что он может, и не тратит пространство, производя из линейных копий тех же функций. Это здорово для оптимизации кода, но не так хорошо для отладки, потому что отладчик не []
оператор позвонить. Это сообщение об ошибке вы видение.
если вы просто хотите увидеть элементы в этом векторе, вы можете использовать lldb "STL Data formatters" чтобы сделать эту работу для вас. Они знают, как выложены большинство типов 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> >) = 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)
вы даже можете использовать фрейм 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
другой способ обойти это для отладки - если вы используете C++11 - это положить:
template class std::vector<MyClass>
в коде где-то. Что будет компилятор выделяет из строки копирует все функции шаблон для этой специализации. Это не отличное общее решение, и вы хотите сделать это только для отладочных сборок, но это позволяет вызывать эти функции и использовать их в сложных выражениях.
аналогичная проблема также происходит со мной: error: Couldn't lookup symbols:
мое решение-явно использовать опрошенную функцию где-то в исходном коде.
#include <vector>
template<typename T>
struct Vector : std::vector<T>
{
Vector(size_t n)
: std::vector<T>{n}
{}
T& operator[](size_t n)
{ return std::vector<T>::operator[](n); }
};
struct XXX
{
int x;
};
void func()
{
std::vector<XXX> a{10};
Vector<XXX> b{10};
auto x = b[0]; // gcc will produce an assembler code of operator[] for debug purpose
1; // as a break point
}
установите точку останова на линии 1; и запустите ее.
(lldb) p a[0]
error: Couldn't lookup symbols:
__ZNSt3__16vectorI3XXXNS_9allocatorIS1_EEEixEm
(lldb) p b[0]
(XXX) = (x = 0)
Бинго!! Существует ли функция в текстовом блоке?
(lldb) image lookup -r -n 'XXX.*operator'
1 match found in /Users/xxx/Library/Developer/Xcode/DerivedData/xxx:
Address: sandbox[0x00000001000011f0] (sandbox.__TEXT.__text + 256)
Summary: sandbox`Vector<XXX>::operator[](unsigned long) at main.cpp:19
я не уверен, но я узнал это раньше. На стадии отладки, а не на стадии производства. Если мы установим точку останова на линии в функции a шаблон, что бы сделал отладчик? Установка точек останова, фактически замена некоторого существующего кода ассемблера на trap или jump, здесь и там везде применяется шаблон? Или просто установить одну точку останова в функции? Он написан как шаблон. Поэтому он должен быть встроен в стадию производства. Однако на этапе отладки функция не является встроенной и записывается как обычная функция. Пожалуйста, не просто верьте тому, что я говорю. Пожалуйста, подтвердите сами. Обратитесь к документации gcc,
clang,
и lldb.
#include <vector>
MacOS 10.13.6, Xcode версии 9.4.1 имеет макрос _LIBCPP_INLINE_VISIBILITY
:
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::reference
vector<_Tp, _Allocator>::operator[](size_type __n)
{
_LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
return this->__begin_[__n];
}
на _LIBCPP_INLINE_VISIBILITY
определена в #include <__config>
as:
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
такие ключевые слова hidden
и __always_inline__
кажется, контролировать поведение.
когда я добавил inline _LIBCPP_INLINE_VISIBILITY
к коду решения образца выше:
inline _LIBCPP_INLINE_VISIBILITY
T& operator[](size_t n)
{ return std::vector<T>::operator[](n); }
в результате:
(lldb) p b[0]
error: Couldn't lookup symbols:
__ZN6VectorI3XXXEixEm
я надеюсь, что помощь и кто-то заглянуть в гораздо больше глубоко.