2016-09-24 16 views
20

Tôi đang cố gắng sử dụng LLDB trong Xcode 8 để gỡ lỗi STL rất cơ bản. Tôi đã từng có thể in một vectơ như thế này:In/Gỡ lỗi libC++ STL với XCode/LLDB

p myvector[0] 

để xem mọi thứ trong chỉ số vector đầu tiên. Bây giờ khi tôi làm điều đó, tôi nhận được lỗi này:

error: Couldn't lookup symbols: 
    __ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm 

Thay vào đó, tôi phải gõ này:

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

tôi đã cố gắng nhập khẩu libcxx.py và các kịch bản unordered_multi.py từ kho LLĐB svn nhưng điều đó dường như không thay đổi gì cả.

Có ai có thể nhận được bất kỳ đầu ra hữu ích nào từ LLDB với libC++ không ??

+0

Bạn đã biên dịch với thông tin gỡ lỗi chưa? Bạn có thể cung cấp một bản sao tự chứa? – EricWF

+1

Tất nhiên thông tin gỡ lỗi được bật. :) Đây là một dự án câm có thể tái tạo vấn đề. Chỉ cần đặt một breakpoint trên std :: cout line và chạy lệnh lldb "p myVector [0]" khi nó chạm. Bạn sẽ gặp lỗi. Nếu bạn làm "p myVector .__ begin_ [0]" thay vào đó nó sẽ in độc đáo. https://www.dropbox.com/s/ntjywxabxj3e4mc/Crap.zip?dl=0 – cjserio

Trả lời

47

[] là phương thức toán tử trên std::vector, vì vậy để in biểu thức bạn muốn, lldb sẽ phải gọi phương thức []. Vấn đề ở đây là STL trên OS X là tích cực về nội tuyến tất cả mọi thứ nó có thể, và không lãng phí không gian sản xuất ra khỏi bản sao dòng của các chức năng tương tự. Đó là điều tuyệt vời cho mã được tối ưu hóa, nhưng không tốt cho việc gỡ lỗi vì nó rời khỏi trình gỡ rối không có nhà điều hành [] nào để gọi. Đó là thông báo lỗi bạn đang thấy.

Nếu bạn chỉ muốn xem các phần tử trong vectơ này, bạn có thể sử dụng lldb "Trình định dạng dữ liệu STL" để thực hiện công việc này cho bạn. Họ biết làm thế nào hầu hết các loại STL được đặt ra, và có thể in các yếu tố của hầu hết các loại container. Ví dụ:

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

nhưng:

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

Ngoài ra còn có một lệnh "khung biến" có thể kiểm tra các đối tượng tĩnh, và móc vào và định dạng dữ liệu. Nó không thể gọi chức năng và làm nhiệm vụ biểu hiện phân tích cú pháp phức tạp hơn khác, nhưng nó không biết làm thế nào để sử dụng và định dạng dữ liệu STL để lấy yếu tố cá nhân:

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

Bạn thậm chí có thể sử dụng tùy chọn khung var của -L để xác định vị trí các yếu tố của vector, và sau đó bạn có thể cast địa chỉ để vượt qua nó để các chức năng khác:

(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 

Một cách khác để làm việc xung quanh này để gỡ lỗi - nếu bạn đang sử dụng C++ 11 - là bằng cách đặt:

template class std::vector<MyClass> 

trong mã của bạn ở đâu đó. Điều đó sẽ hướng dẫn trình biên dịch phát ra các bản sao ngoài dòng của tất cả các hàm mẫu cho chuyên môn này. Đó không phải là một giải pháp chung tuyệt vời, và bạn chỉ muốn thực hiện nó để gỡ lỗi xây dựng, nhưng nó cho phép bạn gọi các hàm này và sử dụng chúng trong các biểu thức phức tạp.

+1

Câu trả lời rất kỹ, Jim, tôi đánh giá cao nó! – cjserio

+0

Đánh dấu trang này. Rất hữu ích! –

+0

Tôi thấy cùng một hành vi trên Linux (Ubuntu 16.10) với clang/lldb 3.9. Nhưng gcc/gdb không gặp rắc rối với '(gdb) p my_vec [0]'. Tôi tự hỏi họ đang làm gì khác. –

Các vấn đề liên quan