Làm cách nào để in các phần tử của vectơ C ++ trong GDB?


210

Tôi muốn kiểm tra nội dung của một std::vectortrong GDB, làm thế nào để tôi làm điều đó? Hãy nói rằng đó là mộtstd::vector<int> vì đơn giản.


3
Câu hỏi tương tự: stackoverflow.com/questions/427589/ Sự (liên kết trong câu trả lời rất thú vị).
Paolo Tedesco

Cách mới, tốt hơn để làm điều này là trong câu hỏi này: stackoverflow.com/questions/2492020/iêu
dshepherd

Câu trả lời:


79

Để xem nội dung vector std :: vector myVector, chỉ cần nhập GDB:

(gdb) print myVector

Điều này sẽ tạo ra một đầu ra tương tự như:

$1 = std::vector of length 3, capacity 4 = {10, 20, 30}

Để đạt được điều trên, bạn cần phải có gdb 7 (tôi đã thử nghiệm nó trên gdb 7.01) và một số máy in đẹp python. Quá trình cài đặt này được mô tả trên wiki gdb .

Hơn nữa, sau khi cài đặt ở trên, điều này hoạt động tốt với GUI gỡ lỗi Eclipse C ++ (và bất kỳ IDE nào khác sử dụng GDB, như tôi nghĩ).


16
Điều này hoạt động tốt miễn là các yếu tố vector có thể giải thích trực tiếp. Nhưng nó không có ích nếu vectơ chứa con trỏ tới các mục quan tâm.
wallyk

Tôi thực sự không tìm thấy trang wiki gdb đặc biệt dễ đọc, có lẽ vì bây giờ nó "hơi" lỗi thời? Ví dụ, tôi có ấn tượng rằng nội dung được đề xuất $HOME/.gdbinitlà cần thiết. Hiện tại tôi không có tập tin nào như vậy cả và gdbhiển thị chính xác nội dung của std::vector. Tuy nhiên, vì trong những lần thử "lan man" của tôi, tôi chỉ cài đặt và sau đó cgdbchưa được libstdc++5cài đặt và tôi đã cài đặt, tôi không biết tại sao bản in đẹp không hoạt động trong khi bây giờ nó hoạt động.
Enrico Maria De Angelis

257

Với GCC 4.1.2, để in toàn bộ std :: vector <int> được gọi là myVector, hãy làm như sau:

print *(myVector._M_impl._M_start)@myVector.size()

Để chỉ in các phần tử N đầu tiên, hãy làm:

print *(myVector._M_impl._M_start)@N

Giải trình

Điều này có thể phụ thuộc nhiều vào phiên bản trình biên dịch của bạn, nhưng đối với GCC 4.1.2, con trỏ tới mảng bên trong là:

myVector._M_impl._M_start 

Và lệnh GDB để in N phần tử của một mảng bắt đầu từ con trỏ P là:

print P@N

Hoặc, ở dạng ngắn (đối với .gdbinit tiêu chuẩn):

p P@N

4
Hehe, đó là thứ gì đó đã làm tôi chán nản trước đây, vì vậy tôi chỉ cần nhìn nó sáng nay và thêm nó như một bản ghi nhớ cho chính mình (như chính Jeff đề nghị).
John Carter

3
Ngoài ra nếu bạn chỉ muốn một phần tử vectơ cụ thể, myVector._M_impl._M_start + n (đối với phần tử thứ n)
mariner

1
Không làm việc cho tôi. Cannot evaluate function -- may be inlined
wallyk

1
Để in một phần tử, ví dụ: phần tử thứ 2: print (myVector._M_impl._M_start) [2]
jfritz42

2
Để tìm tên đặc biệt ( _M_implv.v.) cho trình biên dịch của bạn trong GDB 7.0+, hãy sử dụngprint /r myVector
Eponymous

14

'Xem' STL container trong khi gỡ lỗi là một vấn đề. Dưới đây là 3 giải pháp khác nhau tôi đã sử dụng trong quá khứ, không có giải pháp nào là hoàn hảo.

1) Sử dụng tập lệnh GDB từ http://clith.com/gdb_stl_utils/ Các tập lệnh này cho phép bạn in nội dung của hầu hết các bộ chứa STL. Vấn đề là điều này không hoạt động đối với các container lồng nhau như một tập hợp các tập hợp.

2) Visual Studio 2005 hỗ trợ tuyệt vời để xem các container STL. Điều này hoạt động cho các thùng chứa lồng nhau nhưng điều này chỉ dành cho việc triển khai STL và không hoạt động nếu bạn đặt một container STL trong một thùng chứa Boost.

3) Viết chức năng (hoặc phương thức) in của riêng bạn cho mục cụ thể bạn muốn in trong khi gỡ lỗi và sử dụng 'cuộc gọi' trong khi ở GDB để in mục đó. Lưu ý rằng nếu chức năng in của bạn không được gọi ở bất kỳ đâu trong mã g ++ sẽ thực hiện loại bỏ mã chết và chức năng 'in' sẽ không được tìm thấy bởi GDB (bạn sẽ nhận được thông báo nói rằng chức năng này được nội tuyến). Vì vậy, biên dịch với -fkeep-inline-Hàm


11

đặt nội dung sau vào ~ / .gdbinit

define print_vector
    if $argc == 2
        set $elem = $arg0.size()
        if $arg1 >= $arg0.size()
            printf "Error, %s.size() = %d, printing last element:\n", "$arg0", $arg0.size()
            set $elem = $arg1 -1
        end
        print *($arg0._M_impl._M_start + $elem)@1
    else
        print *($arg0._M_impl._M_start)@$arg0.size()
    end
end

document print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display
end

Sau khi khởi động lại gdb (hoặc tìm nguồn cung ứng ~ / .gdbinit), hãy hiển thị trợ giúp liên quan như thế này

gdb) help print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display

Ví dụ sử dụng:

(gdb) print_vector videoconfig_.entries 0
$32 = {{subChannelId = 177 '\261', sourceId = 0 '\000', hasH264PayloadInfo = false, bitrate = 0,     payloadType = 68 'D', maxFs = 0, maxMbps = 0, maxFps = 134, encoder = 0 '\000', temporalLayers = 0 '\000'}}

2
Cảm ơn bạn vì mật mã! Tôi đoán có một lỗi đánh máy và "print * ($ arg0._M_impl._M_start + $ elem) @ 1" nên là "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? Tôi sử dụng sửa đổi sau: xác định print_vector nếu $ argc == 2 if $ arg1> = $ arg0.size () - 1 printf "Error,% s.size () =% d, in phần tử cuối cùng: \ n", " $ arg0" , $ arg0.size () - 1 end in * ($ arg0._M_impl._M_start + $ arg1) @ 1 khác in * ($ arg0._M_impl._M_start) @ $ arg0.size () end end
user1541776

el tráng lệ! mochas gracias
Truthadjustr

0

Một chút muộn cho bữa tiệc, vì vậy chủ yếu là một lời nhắc nhở cho tôi lần sau khi tôi thực hiện tìm kiếm này!

Tôi đã có thể sử dụng:

p/x *(&vec[2])@4

để in 4 phần tử (dưới dạng hex) từ veclúc bắt đầu vec[2].

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.