Ошибка утверждения lldb при попытке распечатать вектор

я получаю ошибку

lldb: /home/hannes/.llvm/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp:2271: uint64_t ::RecordLayoutBuilder::updateExternalFieldOffset(const clang::FieldDecl *, uint64_t): Утверждение `ExternalFieldOffsets.find( Поле) != ExternalFieldOffsets.end() && "Поле не имеет внешнего смещения"' не удалось. Прервано (сброшено ядро)

когда я пытаюсь напечатать vector<string>. Кто-нибудь знает, почему это происходит, и как это исправить? Эквивалент отлично работает в gdb (есть ряд причин, по которым я предпочел бы использовать / have для использования lldb вместо gdb).

Я использую Ubuntu 12.10 с магистралью llvm, clang и lldb.

Программа, инструкции по сборке и последовательность команд lldb:

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

using std::for_each;
using std::begin;
using std::end;

int main() {
    std::vector<std::string> vec{"Hello","World","!"};
    for_each(begin(vec),end(vec),[](const std::string& s) {
    std::cout << s << " ";
      });
    std::cout << std::endl;
    return 0;
}

clang++ -g -c -std=c++11 main.cpp
clang++ -std=c++11 main.o -o test

lldb test 
Current executable set to 'test' (x86_64).
(lldb) break -n main
invalid command 'breakpoint -n'
(lldb) breat set -n main
error: 'breat' is not a valid command.
(lldb) break set -n main
Breakpoint 1: where = test`main + 26 at main.cpp:5, address = 0x0000000000400aea
(lldb) run
Process 24489 launched: '/home/hannes/Documents/Programming/CXX/test/test' (x86_64)
Process 24489 stopped
* thread #1: tid = 0x5fa9, 0x0000000000400aea test`main + 26 at main.cpp:5, stop reason = breakpoint 1.1
    frame #0: 0x0000000000400aea test`main + 26 at main.cpp:5
   2    #include <string>
   3    
   4    int main() {
-> 5        std::vector<std::string> vec{"Hello","World","!"};
   6        return 0;
   7    }
n
Process 24489 stopped
* thread #1: tid = 0x5fa9, 0x0000000000400c72 test`main + 418 at main.cpp:6, stop reason = step over
    frame #0: 0x0000000000400c72 test`main + 418 at main.cpp:6
   3    
   4    int main() {
   5        std::vector<std::string> vec{"Hello","World","!"};
-> 6        return 0;
   7    }
frame variable
lldb: /home/hannes/.llvm/llvm/tools/clang/lib/AST/RecordLayoutBuilder.cpp:2271: uint64_t <anonymous namespace>::RecordLayoutBuilder::updateExternalFieldOffset(const clang::FieldDecl *, uint64_t): Assertion `ExternalFieldOffsets.find(Field) != ExternalFieldOffsets.end() && "Field does not have an external offset"' failed.
Aborted (core dumped)

Вывод журнала с уровнем отладки 10:

Logging from function (<frame object at 0x3172f20>, '/usr/lib/python2.7/dist-packages/lldb/formatters/cpp/gnu_libstdcpp.py', 141, '__init__', ['\t\tlogger = lldb.formatters.Logger.Logger()\n'], 0)
Providing synthetic children for a map named vec
Logging from function (<frame object at 0x3170d10>, '/usr/lib/python2.7/dist-packages/lldb/formatters/cpp/gnu_libstdcpp.py', 214, 'update', ['\t\tlogger = lldb.formatters.Logger.Logger()\n'], 0)

person Cubic    schedule 25.02.2013    source источник


Ответы (1)


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

person Enrico Granata    schedule 26.02.2013
comment
frame variable --raw работает как положено. Так что да, похоже, проблема в форматтерах данных. - person Cubic; 26.02.2013
comment
Интересный. Чтобы помочь разобраться, непосредственно перед попыткой выгрузки вектора введите: ), затем введите команду. журнал должен содержать некоторую информацию, которая поможет выяснить, где произошел сбой LLDB. - person Enrico Granata; 27.02.2013
comment
Это умирает в update(). Что делает обновление (основная часть работы): impl = self.valobj.GetChildMemberWithName ('_M_impl') self.start = impl.GetChildMemberWithName ('_M_start') self.finish = impl. = impl.GetChildMemberWithName('_M_end_of_storage') self.data_type = self.start.GetType().GetPointeeType() self.data_size = self.data_type.GetByteSize() - person Enrico Granata; 28.02.2013
comment
Хорошим способом выяснить это было бы добавить после каждого лайка в update() (это по пути, который вы видите в записи журнала) строки для эффекта logger ›› «Я сделал это», logger ›› « Я сделал это» и посмотрите, какой шаг умирает. Если выяснится, что мы умираем, извлекая что-то, возможно, пришло время для отчета BugZilla. - person Enrico Granata; 28.02.2013
comment
Кроме того, ведение журнала для средств форматирования данных LLDB не является оптимальным по ряду причин (главным образом, LLDB API не предоставляет доступ к внутреннему средству ведения журнала отладчика, поэтому средства форматирования в конечном итоге имеют свою собственную реализацию средства ведения журнала — и независимо от того, сведено к минимуму по соображениям производительности) - person Enrico Granata; 28.02.2013