2013-07-23 33 views
18

Tiếp theo là mã nguồn của tôi:Kiểm tra tăng shared_ptr với gdb

#include <iostream> 
#include <boost/shared_ptr.hpp> 

class MyClass 
{ 
    public: 
     MyClass() 
     { 
      i=10; 
     } 
    private: 
     int i; 
}; 


int main(int argc, const char *argv[]) 
{ 
    boost::shared_ptr <MyClass> obj(new MyClass()); 
    return 0; 
} 

Tôi muốn kiểm tra obj trong gdb, và xem giá trị của biến thành viên i.

Đây là những gì tôi nhận được với in bình thường:

29   boost::shared_ptr <MyClass> obj(new MyClass()); 
(gdb) n 
30   return 0; 
(gdb) p obj 
$1 = {px = 0x602010, pn = {pi_ = 0x602030}} 

tôi đã cố gắng đầu đề cập trong this link, nhưng không hoạt động.

(gdb) call (obj.get())->print() 
Cannot evaluate function -- may be inlined 

Còn cách nào khác không? Phiên bản gdb là 7.0.1.

+0

Một người bạn cũ tốt là đồng bằng printf:) –

+1

@ Anand Rathi ..., vâng, nhưng tôi chỉ muốn biết nếu điều này là có thể với gdb. –

Trả lời

28

OK.!

(gdb) set print pretty 
(gdb) p obj 
$5 = { 
    px = 0x602010, 
    pn = { 
    pi_ = 0x602030 
    } 
} 
(gdb) p obj.px 
$6 = (MyClass *) 0x602010 



(gdb) p *(obj.px) 
$7 = { 
    i = 10 
} 
+3

Đây là điều hữu ích nhất tôi từng thấy cả ngày !!! Cảm ơn một tấn. Tôi đã không nhận ra rằng tôi có thể dereference con trỏ theo cách đó. :-) – kmort

+3

Điều này không hiệu quả đối với tôi. "p obj" cho '$ 2 = std :: shared_ptr (số 2, yếu 1) 0x639268' và" p obj.px "cho' Không có thành viên hoặc phương thức có tên px'. Tôi cũng đã thử "p * obj", nhưng không có niềm vui: 'Không thể tìm thấy toán tử * .' –

0

Đây sẽ là câu hỏi khó trả lời. GDB 7.x đã thêm hỗ trợ tập lệnh Python. Có một số tài nguyên trên web. Thay vì thực hiện một nỗ lực nghèo để tư vấn về một cái gì đó tôi không có kinh nghiệm đầu tiên trong, tôi sẽ giới thiệu bạn đến một bài qua:

C++ GDB Python Pretty Printing Tutorial?

0

Khi bạn biên dịch tùy chọn -ggdb sử dụng và xem nếu mà làm việc

http://sourceware.org/gdb/onlinedocs/gdb/Inline-Functions.html

nội tuyến là một tối ưu hóa mà chèn một bản sao của cơ quan chức năng trực tiếp tại mỗi địa điểm cuộc gọi, thay vì nhảy đến một thói quen chia sẻ. gdb hiển thị các hàm nội tuyến giống như các hàm không được gạch chân. Chúng xuất hiện trong backtraces. Bạn có thể xem đối số của họ và biến địa phương, bước vào chúng với bước, bỏ qua chúng với tiếp theo, và thoát khỏi chúng với kết thúc. Bạn có thể kiểm tra xem một hàm đã được inlined hay chưa bằng cách sử dụng lệnh khung thông tin.

Để gdb hỗ trợ các chức năng nội tuyến, trình biên dịch phải ghi lại thông tin về nội tuyến trong thông tin gỡ lỗi - gcc sử dụng định dạng lùn 2, và một số trình biên dịch khác cũng có. gdb chỉ hỗ trợ chức năng nội tuyến khi sử dụng dwarf 2. Phiên bản gcc trước 4.1 không phát ra hai thuộc tính bắt buộc (‘DW_AT_call_file’ và ‘DW_AT_call_line’); gdb không hiển thị các cuộc gọi hàm nội tuyến với các phiên bản trước của gcc. Thay vào đó, nó sẽ hiển thị các đối số và biến cục bộ của các hàm nội tuyến dưới dạng các biến cục bộ trong trình gọi.

Nội dung của hàm được gạch chân được bao gồm trực tiếp tại trang web cuộc gọi; không giống như một chức năng không được gạch chân, không có hướng dẫn nào dành cho cuộc gọi. gdb vẫn giả vờ rằng trang web cuộc gọi và bắt đầu của hàm nội tuyến là các hướng dẫn khác nhau. Bước tới trang cuộc gọi hiển thị trang cuộc gọi, sau đó bước lại cho thấy dòng đầu tiên của hàm nội tuyến, mặc dù không có hướng dẫn bổ sung nào được thực thi.

Điều này làm cho việc gỡ lỗi ở cấp nguồn rõ ràng hơn nhiều; bạn có thể thấy cả ngữ cảnh của cuộc gọi và sau đó là hiệu ứng của cuộc gọi. Chỉ có một bước bằng cách sử dụng stepi hoặc nexti không làm điều này; các bước chỉ dẫn duy nhất luôn hiển thị nội dung được nội tuyến.

Có một số cách mà gdb không giả vờ rằng các cuộc gọi chức năng inlined đều giống nhau như các cuộc gọi thông thường:

Thiết breakpoint tại trang web tiếng gọi của một chức năng inlined thể không làm việc, bởi vì các trang web gọi không chứa bất kỳ mã. gdb có thể di chuyển không chính xác điểm ngắt đến dòng tiếp theo của hàm kèm theo, sau cuộc gọi. Giới hạn này sẽ bị loại bỏ trong một phiên bản gdb tương lai; cho đến lúc đó, hãy đặt một điểm ngắt trên một dòng trước đó hoặc bên trong hàm nội tuyến thay vào đó. gdb không thể xác định giá trị trả về của các cuộc gọi nội tuyến sau khi sử dụng lệnh kết thúc.Đây là giới hạn của thông tin gỡ rối do trình biên dịch tạo ra; sau khi kết thúc, bạn có thể bước tới dòng tiếp theo và in một biến mà chương trình của bạn lưu trữ giá trị trả về.

2

Hãy thử điều này:

in (* obj.px) .Tôi

mã hoàn chỉnh là dưới đây:

(gdb) list 1,23 
1  #include <iostream> 
2  #include <boost/shared_ptr.hpp> 
3  #include <string> 
4 
5  class MyClass 
6  { 
7   public: 
8    MyClass() 
9     : name("Testing") 
10    { 
11     i=10; 
12    } 
13   private: 
14    int i; 
15    std::string name; 
16  }; 
17 
18 
19  int main(int argc, const char *argv[]) 
20  { 
21   boost::shared_ptr <MyClass> obj(new MyClass()); 
22   return 0; 
23  } 
(gdb) p obj 
$9 = {px = 0x602010, pn = {pi_ = 0x602060}} 
(gdb) p (*obj.px).i 
$10 = 10 
(gdb) p (*obj.px).name 
$11 = {static npos = 18446744073709551615, 
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x602048 "Testing"}}