У меня есть объект, определенный в c ++ с указателем на него, используемый в различных функциях и файлах по всему проекту. У меня проблема с обновляемыми данными, поэтому я хочу отладить их, чтобы увидеть, что происходит. В идеале я хочу разбивать каждый раз, когда к объекту обращаются. тем не мение, watch
требует определенного адреса памяти. Так, например, если у меня есть:
class data{
public:
int a;
int b;
};
тогда GDB сломается только когда a
изменен, так как указатель на данные указывает на a
, но не когда b
изменен.
Есть ли способ сломать всякий раз, когда весь диапазон памяти покрыт data
класс изменился?
Есть ли способ сломаться всякий раз, когда изменяется весь диапазон памяти, охватываемый классом данных?
Может быть.
Аппаратные контрольные точки GDB используют специальные аппаратные регистры отладки, и обычно существует ограничение на работу таких регистров. На x86
, вы можете установить до 4-х словесных аппаратных точек наблюдения, например, вы дали вам Можно установить точки наблюдения на &data->a
а также &data->b
и это «покроет» всю память о data
,
Я предполагаю, что ваш фактический data
имеет гораздо больше членов, поэтому 4-х точечных часовых слов будет недостаточно.
Если вы находитесь на платформе, которая поддерживает Valgrind, и если ваша программа может выполняться под Valgrind, вы можете использовать встроенный в Valgrind gdbserver установить точки наблюдения на произвольный области памяти.
Обновить:
Я просмотрел страницу, на которую вы ссылались, и не смог найти то, что искал
Я не уверен, что вы искали. Вот пример сеанса, показывающий, как это работает:
#include <stdlib.h>
void foo(char *p)
{
*p = 'a';
}
typedef struct {
char buf[1024];
} data;
int main()
{
data *d = calloc(1, sizeof(data));
foo(d->buf + 999);
}
gcc -g main.c
valgrind --vgdb-error=0 ./a.out
...
==10345== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==10345== /path/to/gdb ./a.out
==10345== and then give GDB the following command
==10345== target remote | vgdb --pid=10345
… Valgrind теперь ожидает присоединения отладчика.
В другом окне:
gdb ./a.out
GNU gdb (GDB) 7.4
...
(gdb) target remote | vgdb --pid=10345
relaying data between gdb and process 10345
[Switching to Thread 10345]
0x0000000004000af0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) b main
Breakpoint 1 at 0x40053d: file main.c, line 14.
(gdb) c
Breakpoint 1, main () at main.c:14
14 data *d = calloc(1, sizeof(data));
(gdb) n
15 foo(d->buf + 999);
(gdb) watch *d
Hardware watchpoint 2: *d
Обратите внимание, что «аппаратная» точка наблюдения была установлена на все *d
,
Это аппаратная точка наблюдения только в том смысле, что Valgrind является аппаратным обеспечением.
(gdb) p d.buf[999]
$1 = 0 '\000'
(gdb) c
Hardware watchpoint 2: *d
Old value = {buf = '\000' <repeats 1023 times>}
New value = {buf = '\000' <repeats 999 times>, "a", '\000' <repeats 23 times>}
foo (p=0x51b6457 "a") at main.c:6
6 }
(gdb) q
Вуаля: отладчик остановился, когда 999-й элемент был изменен, доказав, что точка наблюдения «покрыла» всю структуру.
Других решений пока нет …