簡體   English   中英

我可以在 GDB 中的“內存訪問”上設置斷點嗎?

[英]Can I set a breakpoint on 'memory access' in GDB?

我正在通過 gdb 運行應用程序,並且我想在任何時候訪問/更改特定變量時設置斷點。 有沒有這樣做的好方法? 我也對在 C/C++ 中監視變量以查看它是否/何時更改的其他方法感興趣。

watch只在寫時中斷, rwatch讓你在讀時中斷, awatch讓你在讀/寫時中斷。

您可以在 memory 位置設置讀取觀察點:

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

但一個限制適用於 rwatch 和 awatch 命令; 您不能在表達式中使用 gdb 變量:

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

所以你必須自己擴展它們:

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

編輯:哦,順便說一句。 您需要硬件或軟件支持 軟件顯然要慢得多。 要了解您的操作系統是否支持硬件觀察點,您可以查看can-use-hw-watchpoints環境設置。

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

您要查找的內容稱為watchpoint

用法

(gdb) watch foo : 觀察變量foo的值

(gdb) watch *(int*)0x12345678 :觀察地址指向的值,轉換為你想要的任何類型

(gdb) watch a*b + c/d : 觀察任意復雜的表達式,在程序的母語中有效

觀察點分為三種:

  • 觀看:發生寫入時 gdb 將中斷
  • rwatch :gdb 將在發生讀取時中斷
  • awatch : gdb 在這兩種情況下都會中斷

您可以選擇更適合您需要的。

有關更多信息,請查看 內容。

假設第一個答案是指類似 C 的語法(char *)(0x135700 +0xec1a04f)那么執行rwatch *0x135700+0xec1a04f的答案是不正確的。 正確的語法是rwatch *(0x135700+0xec1a04f)

那里缺少()給我自己嘗試使用觀察點帶來了很大的痛苦。

我剛剛嘗試了以下方法:

 $ 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

所以這似乎是可能的,但你似乎確實需要一些硬件支持。

如上所述,使用 watch 查看何時寫入變量,讀取時使用 rwatch,讀取/寫入時使用 awatch。 但是,請注意,要使用該命令,您必須中斷程序,並且當您中斷程序時,變量必須在 scope 中:

使用 watch 命令。 watch 命令的參數是一個被計算的表達式。 這意味着您要設置觀察點的變量必須在當前 scope 中。 因此,要在非全局變量上設置觀察點,您必須設置一個斷點,該斷點將在變量位於 scope 時停止您的程序。 您在程序中斷后設置觀察點。

除了asksolPaolo M已經回答/評論的內容

起初我沒有讀明白,為什么我們需要轉換結果。 雖然我讀到這個: https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html ,但它對我來說並不直觀......

所以我做了一個實驗讓結果更清楚: 代碼:(假設 int main() 在第 3 行; int i=0 在第 5 行,其他代碼.. 來自第 10 行)

int main()
{
int i = 0;
int j;
i = 3840 // binary 1100 0000 0000 to take into account endianness
other code..
}

然后我第一次嘗試使用可執行文件啟動 gdb,我在變量的位置設置斷點而不進行強制轉換,以下是顯示的結果

Thread 1 "testing2" h
Breakpoint 2 at 0x10040109b: file testing2.c, line 10.
(gdb) s
7           i = 3840;
(gdb) p i
$1 = 0
(gdb) p &i
$2 = (int *) 0xffffcbfc
(gdb) watch *0xffffcbfc
Hardware watchpoint 3: *0xffffcbfc
(gdb) s
[New Thread 13168.0xa74]

Thread 1 "testing2" hit Breakpoint 2, main () at testing2.c:10
10          b = a;
(gdb) p i
$3 = 3840
(gdb) p *0xffffcbfc
$4 = 3840
(gdb) p/t *0xffffcbfc
$5 = 111100000000

正如我們所見,我設置的第 10 行出現斷點。 gdb 沒有中斷,因為雖然變量我經歷了變化,但被觀察的位置沒有改變(由於字節順序,因為它繼續保持全 0)

在我的第二次嘗試中,我對變量的地址進行了強制轉換以監視所有 sizeof(int) 字節。 這次:

(gdb) p &i
$6 = (int *) 0xffffcbfc
(gdb) p i
$7 = 0
(gdb) watch *(int *) 0xffffcbfc
Hardware watchpoint 6: *(int *) 0xffffcbfc
(gdb) b 10
Breakpoint 7 at 0x10040109b: file testing2.c, line 10.
(gdb) i b
Num     Type           Disp Enb Address            What
6       hw watchpoint  keep y                      *(int *) 0xffffcbfc
7       breakpoint     keep y   0x000000010040109b in main at testing2.c:10
(gdb) n
[New Thread 21508.0x3c30]

Thread 1 "testing2" hit Hardware watchpoint 6: *(int *) 0xffffcbfc

Old value = 0
New value = 3840

Thread 1 "testing2" hit Breakpoint 7, main () at testing2.c:10
10          b = a;

gdb 中斷,因為它檢測到值已更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM