Могу ли я установить точку останова на «доступе к памяти» в GDB?
-
09-06-2019 - |
Вопрос
Я запускаю приложение через GDB и хочу установить точку останова на каждый раз, когда осуществляется доступ или изменение определенной переменной.Есть ли хороший способ сделать это?Мне также были бы интересны другие способы мониторинга переменной в C/C++, чтобы увидеть, меняется ли она и когда.
Решение
смотреть прерывается только при записи, смотреть позвольте вам прерваться на чтение, и Часы позвольте вам прервать чтение/запись.
Вы можете установить точки наблюдения за чтением в ячейках памяти:
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.
Другие советы
Предполагая, что первый ответ относится к синтаксису C-подобного типа. (char *)(0x135700 +0xec1a04f)
тогда ответ, который нужно сделать rwatch *0x135700+0xec1a04f
это неверно.Правильный синтаксис: rwatch *(0x135700+0xec1a04f)
.
Отсутствие ()
Это причинило мне много боли, когда я пытался самостоятельно использовать точки наблюдения.
То, что вы ищете, называется наблюдательный пункт.
Применение
(gdb) watch foo
:следить за ценностью переменная foo
(gdb) watch *(int*)0x12345678
:наблюдайте за значением, указанным адрес, приведенный к любому типу, который вы хотите
(gdb) watch a*b + c/d
:смотреть произвольно сложное выражение, действительно на родном языке программы
Точки наблюдения бывают трех видов:
- смотреть:GDB сломается, когда писать имеет место
- смотреть:GDB сломается, когда читать имеет место
- Часы:GDB вломится оба случая
Вы можете выбрать более подходящий для ваших нужд.
Для получения дополнительной информации проверьте этот вне.
Я только что попробовал следующее:
$ 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, когда она читается, и наблюдайте, когда она читается/записывается из/в, как отмечено выше.Однако учтите, что для использования этой команды необходимо сломать программу, а переменная должна находиться в области видимости, когда вы сломали программу:
Используйте команду просмотра.Аргумент в команде Watch - это выражение, которое оценивается.Это подразумевает, что вариабель, на которой вы хотите установить точку наблюдения, должна быть в текущей области.Таким образом, чтобы установить точку наблюдения на неглобальной переменной, вы должны установить точку остановки, которая остановит вашу программу, когда переменная находится в объеме.Вы устанавливаете Watchpoint после того, как программа разрывается.