Tôi có thể đặt điểm dừng trên 'truy cập bộ nhớ' trong GDB không?


244

Tôi đang chạy một ứng dụng thông qua gdb và tôi muốn đặt điểm dừng cho bất kỳ khi nào một biến cụ thể được truy cập / thay đổi. Có một phương pháp tốt để làm điều này? Tôi cũng sẽ quan tâm đến các cách khác để theo dõi một biến trong C / C ++ để xem nếu / khi nó thay đổi.

Câu trả lời:


286

xem chỉ nghỉ khi viết, rwatch cho phép bạn đọc và đọc cho phép bạn đọc / ghi.

Bạn có thể đặt các điểm quan sát đọc trên các vị trí bộ nhớ:

gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface

nhưng một giới hạn áp dụng cho các lệnh rwatch và awatch; bạn không thể sử dụng biến gdb trong biểu thức:

gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.

Vì vậy, bạn phải tự mở rộng chúng:

gdb$ print $ebx 
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f

Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()

Chỉnh sửa: Ồ, và nhân tiện. Bạn cần hỗ trợ phần cứng hoặc phần mềm . Phần mềm rõ ràng là chậm hơn nhiều. Để tìm hiểu xem hệ điều hành của bạn có hỗ trợ các điểm giám sát phần cứng hay không, bạn có thể xem cài đặt môi trường có thể sử dụng hw-watchpoint .

gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.

7
Nếu bạn muốn xem một thành viên của phương pháp C ++, tôi thấy biến thể này vô cùng hữu ích : watch -location mTextFormatted.
Ivan Vučica

Nếu tôi không có địa chỉ của một biến thì sao? Tôi chỉ có thể sử dụng tên của nó?
Raffi Khatchadourian

5
Bạn có thể yêu cầu GDB in địa chỉ của biến bằng địa chỉ của toán tử. print &variable
Loduwijk

1
Câu trả lời này không nói gì về kích thước của vị trí bộ nhớ đang được theo dõi bởi watchcác lệnh. Trong khi đó, đây là câu hỏi đầu tiên xuất hiện trong đầu sau khi đọc những điều trên. Có bao nhiêu byte rwatch *0xfeedfacethực sự sẽ xem?
AnT

8
@AnT, tôi đã giả sử rằng nó sẽ xem một byte đơn, dường như là trường hợp đó, nhưng bạn có thể chuyển nó thành một loại cụ thể, ví dụ như rwatch *(int *)0xfeedfacenó sẽ xem các sizeof(int)byte: sourceware.org/gdb/onlinesocs/gdb/set-Watchpoint. html
Askol

28

Những gì bạn đang tìm kiếm được gọi là một quan điểm .

Sử dụng

(gdb) watch foo: xem giá trị của biến foo

(gdb) watch *(int*)0x12345678: xem giá trị được chỉ bởi một địa chỉ , được chuyển thành bất kỳ loại nào bạn muốn

(gdb) watch a*b + c/d: xem một biểu thức phức tạp tùy ý , hợp lệ bằng ngôn ngữ bản địa của chương trình

Quan điểm có ba loại:

  • xem : gdb sẽ bị hỏng khi xảy ra ghi
  • rwatch : gdb sẽ phá vỡ wnen một đọc xảy ra
  • awatch : gdb sẽ phá vỡ trong cả hai trường hợp

Bạn có thể chọn phù hợp hơn cho nhu cầu của bạn.

Để biết thêm thông tin, kiểm tra này .


5
Tôi đã viết một câu trả lời khác bởi vì những câu hỏi hiện tại dường như không đơn giản với tôi ...
Paolo M

25

Giả sử câu trả lời đầu tiên là nói đến cú pháp giống như C (char *)(0x135700 +0xec1a04f)thì câu trả lời phải làm rwatch *0x135700+0xec1a04flà không chính xác. Cú pháp đúng là rwatch *(0x135700+0xec1a04f).

Việc thiếu ()s ở đó khiến tôi rất đau đớn khi cố gắng tự mình sử dụng các điểm quan sát.


9

Tôi chỉ thử như sau:

 $ cat gdbtest.c
 int abc = 43;

 int main()
 {
   abc = 10;
 }
 $ gcc -g -o gdbtest gdbtest.c
 $ gdb gdbtest
 ...
 (gdb) watch abc
 Hardware watchpoint 1: abc
 (gdb) r
 Starting program: /home/mweerden/gdbtest 
 ...

 Old value = 43
 New value = 10
 main () at gdbtest.c:6
 6       }
 (gdb) quit

Vì vậy, có vẻ như có thể, nhưng bạn dường như cần một số hỗ trợ phần cứng.


Nếu nền tảng của bạn không hỗ trợ các điểm giám sát phần cứng, gdb sẽ quay trở lại điểm xem phần mềm.
Tod

2

Sử dụng đồng hồ để xem khi nào một biến được ghi vào, rwatch khi nó được đọc và bắt đầu khi nó được đọc / ghi từ / đến, như đã lưu ý ở trên. Tuy nhiên, xin lưu ý rằng để sử dụng lệnh này, bạn phải ngắt chương trình và biến phải nằm trong phạm vi khi bạn phá vỡ chương trình:

Sử dụng lệnh xem. Đối số cho lệnh watch là một biểu thức được ước tính. Điều này ngụ ý rằng variabel bạn muốn đặt điểm theo dõi phải nằm trong phạm vi hiện tại. Vì vậy, để đặt điểm theo dõi trên một biến không toàn cầu, bạn phải đặt một điểm dừng sẽ dừng chương trình của bạn khi biến đó nằm trong phạm vi. Bạn đặt điểm theo dõi sau khi chương trình nghỉ.

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.