GDB'de 'bellek erişimi' için bir kesme noktası ayarlayabilir miyim?


244

Ben gdb üzerinden bir uygulama çalıştırıyorum ve belirli bir değişken erişilir / değiştirilir her zaman için bir kesme noktası ayarlamak istiyorum. Bunu yapmak için iyi bir yöntem var mı? Ayrıca değişip değişmediğini / ne zaman görmek için C / C ++ bir değişkeni izlemek için başka yollarla da ilgilenirim.

Yanıtlar:


286

sadece yazmada molaları izle , rwatch okumaya izin ver ve uyanık ol okuma / yazmaya izin vermenize izin verir.

Bellek konumlarında okuma izleme noktaları ayarlayabilirsiniz:

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

ancak bir sınırlama rwatch ve awatch komutları için geçerlidir; ifadelerde gdb değişkenlerini kullanamazsınız:

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

Yani onları kendiniz genişletmelisiniz:

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

Düzenleme: Oh, ve bu arada. Donanım veya yazılım desteğine ihtiyacınız var . Yazılım açıkçası çok daha yavaş. İşletim sisteminizin donanım izleme noktalarını destekleyip desteklemediğini öğrenmek için can-use-hw-watchpoints ortam ayarını görebilirsiniz.

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

7
Eğer bir C ++ yöntemin bir üyesi izlemek istiyorsanız, bu varyant gayet yararlı buldum: watch -location mTextFormatted.
Ivan Vučica

Değişkenin adresi yoksa ne olur? Sadece adını kullanabilir miyim?
Raffi Khatchadourian

5
GDB'nin değişkenin adresini operatör adresiyle yazmasını sağlayabilirsiniz. print &variable
Loduwijk

1
Bu yanıt, komutların izlediği bellek konumunun boyutu hakkında hiçbir şey söylemez watch. Bu arada, yukarıdakileri okuduktan sonra akla gelen ilk soru budur. rwatch *0xfeedfaceAslında kaç bayt izleyecek?
AnT

8
@AnT, durumun böyle göründüğü gibi tek bir bayt izleyeceğini varsayıyordum, ancak örneğin belirli bir türe atabilirsiniz rwatch *(int *)0xfeedfaceve sizeof(int)baytları izleyecektir : sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints. html
asksol

28

Aradığın noktaya izleme noktası denir .

kullanım

(gdb) watch foo: değişkenin değerini izle foo

(gdb) watch *(int*)0x12345678: ne tür olursa olsun bir adresin işaret ettiği değeri izleyin

(gdb) watch a*b + c/d: programın ana dilinde geçerli olan rastgele karmaşık bir ifadeyi izleyin

Gözlem noktaları üç çeşittir:

  • watch : gdb yazma gerçekleştiğinde kırılacak
  • rwatch : gdb bir okuma gerçekleştiğinde kırılacak
  • awatch : gdb her iki durumda da kırılacak

İhtiyaçlarınız için daha uygun olanı seçebilirsiniz.

Daha fazla bilgi için, kontrol bu dışarı.


5
Başka bir cevap yazdım çünkü mevcut olanlar bana çok açık görünmüyordu ...
Paolo M

25

İlk cevabın C benzeri sözdizimine atıfta bulunduğu varsayıldığında, (char *)(0x135700 +0xec1a04f)yapılacak cevap rwatch *0x135700+0xec1a04fyanlıştır. Doğru sözdizimi rwatch *(0x135700+0xec1a04f).

()Oradaki s eksikliği, kendimi gözetleme noktalarını kullanmaya çalışırken büyük bir acıya neden oldu.


9

Sadece aşağıdakileri denedim:

 $ 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

Bu yüzden mümkün görünüyor, ancak bazı donanım desteğine ihtiyacınız var gibi görünüyor.


Platformunuz donanım izleme noktalarını desteklemiyorsa gdb bir yazılım izleme noktasına geri dönmelidir.
Tod

2

Bir değişkenin ne zaman yazıldığını görmek için watch öğesini, okunduğunda rwatch öğesini ve yukarıda belirtildiği gibi / den okunduğunda / yazarken awatch komutunu kullanın. Ancak, bu komutu kullanmak için programı kırmanız ve programı bozduğunuzda değişkenin kapsamda olması gerektiğini lütfen unutmayın:

Watch komutunu kullanın. Watch komutunun argümanı değerlendirilen bir ifadedir. Bu, bir izleme noktası ayarlamak istediğiniz değişkenin geçerli kapsamda olması gerektiği anlamına gelir. Bu nedenle, global olmayan bir değişken üzerinde bir izleme noktası ayarlamak için, değişken kapsamdayken programınızı durduracak bir kesme noktası ayarlamanız gerekir. İzleme noktasını program bozulduktan sonra ayarlayabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.