Оценка выражения с перегруженными операторами в C++ lldb

Я отлаживаю программу на C++ в Xcode 5 с помощью lldb, и я хотел бы оценить произвольные выражения в отладчике, особенно те, которые используют перегруженные операторы.

Например, я создал очень простой проект Xcode 5 C++ со следующим main.cpp и всеми опциями compiler/linker/etc, установленными по умолчанию:

#include <iostream>
#include <vector>

int main(int argc, const char * argv[])
{
  std::vector<int> vec;
  vec.push_back(42);
  std::cout << "vec[0] = " << vec[0] << std::endl;
  return 0;
}

Я установил точку останова на return 0; линия и запустил программу.

Затем в приглашении lldb печать вектора в целом работает нормально:

(lldb) expr vec
(std::__1::vector<int, std::__1::allocator<int> >) $0 = size=1 {
  [0] = 42
}

Тем не менее, я не могу получить доступ к его членам, используя перегруженные operator[]:

(lldb) expr vec[0]
error: call to a function 'std::__1::vector<int, std::__1::allocator<int> >::operator[](unsigned long)' ('_ZNSt3__16vectorIiNS_9allocatorIiEEEixEm') that is not present in the target
error: The expression could not be prepared to run in the target

Точно так же я не могу получить итератор (хотя у меня здесь меньше опыта, поэтому мой синтаксис может быть неправильным):

(lldb) expr vector<int>::iterator it = vec.begin()
error: use of undeclared identifier 'vector'
error: expected '(' for function-style cast or type construction
error: expected '(' for function-style cast or type construction
error: 3 errors parsing expression

а также

(lldb) expr (vector<int>::iterator) vec.begin()
error: use of undeclared identifier 'vector'
error: expected '(' for function-style cast or type construction
error: expected '(' for function-style cast or type construction
error: 3 errors parsing expression

Аналогично, печать простой строки работает нормально:

(lldb) expr string("a")
(std::__1::string) $0 = "a"

Однако простая конкатенация строк завершается неудачно:

(lldb) expr string("a") + string("b")
error: invalid operands to binary expression ('string' (aka 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >') and 'string')
error: 1 errors parsing expression

Что я делаю неправильно? Поддерживает ли lldb оценку с перегруженными операторами?

Заранее спасибо!

2 ответа

Решение

Обратите внимание, что стандартные библиотеки C++ настроены таким образом, что они включают в себя все шаблонные функции, которые могут быть разумно встроены, и реальных копий функций не существует. Так, например, когда вы идете, чтобы позвонить std::vector<int>::begin()нет такой функции. Все его использования были встроены.

Вот почему вы получаете сообщение об ошибке "вызов функции... отсутствует в цели". Там могут быть встроенные копии функции, но ни одна из них мы не можем вызвать. В качестве примера, если я соберу небольшую программу на C++, которая создает std::vector, помещает в нее некоторые элементы, затем выполняет итерацию по ним, а затем выполняет:

    (lldb) image lookup -r -n begin
    2 matches found in /private/tmp/vector:
        Address: vector[0x0000000100000eaf] (vector.__TEXT.__text + 1071)
        Summary: vector`main + 1071 [inlined] std::__1::vector<int, std::__1::allocator<int> >::begin() at vector.cpp:12
                 vector`main + 1071 at vector.cpp:12        Address: vector[0x0000000100000eaf] (vector.__TEXT.__text + 1071)
        Summary: vector`main + 1071 [inlined] std::__1::vector<int, std::__1::allocator<int> >::begin() at vector.cpp:12
                 vector`main + 1071 at vector.cpp:12

Так что все экземпляры начальных и конечных аксессоров для std::vector<int> встроены. И далее в части, которая происходит от самой библиотеки std c:

12 matches found in /usr/lib/libc++.1.dylib:
    Address: libc++.1.dylib[0x000000000003e4ec] (libc++.1.dylib.__TEXT.__text + 252188)
    Summary: libc++.1.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::begin()        Address: libc++.1.dylib[0x000000000003e51c] (libc++.1.dylib.__TEXT.__text + 252236)
    Summary: libc++.1.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::begin() const        Address: libc++.1.dylib[0x000000000003e574] (libc++.1.dylib.__TEXT.__text + 252324)

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

В настоящее время lldb недостаточно умен, чтобы понять, как воссоздать шаблонную функцию / метод из заголовочных файлов стандартной библиотеки C++. Нам не хватает среды, в которой ваш код был изначально скомпилирован, чтобы выполнить эту задачу.

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

Я только столкнулся с той же самой проблемой и очевидно нашел простой обходной путь. Вы можете получить доступ к i- му элементу вектора vec как это:

(lldb) p vec.__begin_[i]
(int) $1 = 100
Другие вопросы по тегам