Чи можна встановити точку розриву на "доступ до пам'яті" в GDB?


244

Я запускаю програму через gdb і хочу встановити точку перерви в будь-який час, коли доступ до певної змінної буде змінено. Чи є хороший метод для цього? Мені б також цікаві інші способи моніторингу змінної в C / C ++, щоб побачити, чи / коли вона змінюється.

Відповіді:


286

дивитись лише перерви на запис, rwatch дозволяють вам перерватися на прочитане, а awatch дозволяють вам порушувати читання / запис.

Ви можете встановити точки зчитування сторожових точок на місцях пам'яті:

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.

7
Якщо ви хочете подивитися елемент методу C ++, я знайшов цей варіант дуже корисним: watch -location mTextFormatted.
Іван Вучиця

Що робити, якщо у мене немає адреси змінної? Чи можу я просто використовувати його ім’я?
Раффі Хатчадурян

5
Ви можете мати GDB друкувати адресу змінної разом з оператором address. print &variable
Loduwijk

1
Ця відповідь нічого не говорить про розмір місця в пам'яті, який спостерігають watchкоманди. Тим часом, це питання про кулак, що виникає після прочитання вище. Скільки байтів rwatch *0xfeedfaceнасправді буде дивитися?
ANT

8
@AnT, я припускав, що він буде дивитися один байт, що, мабуть, так і є, але ви можете передати його певному типу, наприклад, rwatch *(int *)0xfeedfaceі він буде переглядати sizeof(int)байти: sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints. html
askol

28

Те, що ви шукаєте, називається сторожовою точкою .

Використання

(gdb) watch foo: спостерігати за значенням змінної foo

(gdb) watch *(int*)0x12345678: перегляньте значення, вказане адресою , подане на будь-який тип, який ви хочете

(gdb) watch a*b + c/d: дивіться довільно складний вираз , дійсний рідною мовою програми

Оглядові пункти бувають трьох видів:

  • дивитися : GDB буде перерва , коли запис відбувається
  • rwatch : gdb порушить, якщо відбувається читання
  • awatch : gdb порушиться в обох випадках

Ви можете вибрати більш підходящий для ваших потреб.

Для отримання додаткової інформації перевірте це .


5
Я написав ще одну відповідь, тому що існуючі мені не здалися дуже простими ...
Paolo M

25

Якщо припустити, що перша відповідь посилається на C-подібний синтаксис, (char *)(0x135700 +0xec1a04f)то відповідь робити rwatch *0x135700+0xec1a04fневірно. Правильний синтаксис є rwatch *(0x135700+0xec1a04f).

Відсутність ()там завдала мені великого болю, намагаючись самостійно використовувати пункти спостереження.


9

Я просто спробував таке:

 $ 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

Це здається можливим, але вам здається, що вам потрібна певна апаратна підтримка.


Якщо ваша платформа не підтримує апаратні точки спостереження, gdb повинен повернутися до точки перегляду програмного забезпечення.
Тод

2

Використовуйте watch, щоб побачити, коли змінна записується, rwatch, коли вона читається, і awatch, коли вона читається / пишеться з / в, як зазначено вище Однак зауважте, що для використання цієї команди ви повинні зламати програму, а змінна повинна бути в області застосування, коли ви зламали програму:

Використовуйте команду watch. Аргумент команди watch - це вираження, яке оцінюється. Це означає, що змінна величина, на яку потрібно встановити точку спостереження, повинна знаходитися в поточній області. Отже, щоб встановити точку спостереження на неглобальну змінну, ви повинні встановити точку перелому, яка зупинить вашу програму, коли змінна знаходиться в області застосування. Ви встановлюєте точку спостереження після перерви в програмі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.