GDB останавливается со слишком большим количеством точек наблюдения, когда есть только одна - PullRequest
16 голосов
/ 08 июля 2010

Знаете ли вы какие-либо другие причины, по которым точка наблюдения не может быть вставлена, кроме слишком большого количества аппаратных точек останова / точек наблюдения?

У меня есть следующий сеанс отладки:

GNU gdb (GDB) 7.1
...
(gdb) watch itrap_t_beg[1][222]
Hardware watchpoint 1: itrap_t_beg[1][222]
(gdb) cont
Continuing.
...
Hardware watchpoint 1: itrap_t_beg[1][222]

...
(gdb) cont
Continuing.
Warning:
Could not insert hardware watchpoint 1.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.

(gdb) info break
Num     Type           Disp Enb Address            What
1       hw watchpoint  keep y                      itrap_t_beg[1][222]
        breakpoint already hit 1 time

Как вы можетевидите, есть только одна точка наблюдения, но она не может вставить точку останова.

Знаете, как я могу это исправить?

Ответы [ 3 ]

12 голосов
/ 08 июля 2010

Насколько я знаю, у обычных процессоров x86 есть четыре отладочных регистра , доступных для поддержки аппаратных пауз / часов.Это ограничивает размер объекта, который вы можете наблюдать.Здесь также играет роль выравнивание объектов.

Попробуйте ограничить область наблюдения меньшим объектом, таким как пара первых и последних членов структуры.

9 голосов
/ 15 января 2011

Может принудительно установить программные точки останова (для которых нет ограничений по размеру), запустив

set can-use-hw-watchpoints 0

2 голосов
/ 15 февраля 2017

Выстрел ответа: используйте watch -location itrap_t_beg[1][222], или краткую форму watch -l.

Длинный ответ: Цитирование руководства GDB :

Наблюдение за комплексомвыражения, которые ссылаются на многие переменные, также могут исчерпать ресурсы, доступные для аппаратных точек наблюдения.Это связано с тем, что gdb необходимо отслеживать каждую переменную в выражении с отдельно выделенными ресурсами.

gdb буквально следит за самим выражением, а не по тому адресу, на который оно указывает.В этом случае это означает, что точка останова сработает, если само itrap_t_beg будет изменено так, что itrap_t_beg[1][222] сделает это;есть не только точка наблюдения для itrap_t_beg[1][222], но и точка для itrap_t_beg.Это может быть больше, чем доступно.

В вашем случае itrap_t_beg - это 7 дюймов, 28 байтов.Точка наблюдения x86_64 имеет длину до восьми байт, поэтому GDB требуется четыре точки наблюдения для всей структуры - плюс пятая для самой itrap_t_beg.Семейство x86 поддерживает только четыре одновременные точки наблюдения.

Более подробный пример того, как работают точки наблюдения:

//set a watchpoint on '*p' before running
#include <stdio.h>
int a = 0;
int b = 0;
int c = 0;
int* p = &a;

int main()
{
    puts("Hi"); // Dummy lines to make the results clearer, watchpoints stop at the line after the change
    *p = 1; // Breaks: *p was changed from 0 to 1
    puts("Hi");
    a = 2; // Breaks: a is *p, which changed from 1 to 2
    puts("Hi");
    p = &b; // Breaks: p is now b, changing *p from 2 to 0
    puts("Hi");
    p = &c; // Doesn't break: while p changed, *p is still 0
    puts("Hi");
    p = NULL; // Breaks: *p is now unreadable
    puts("Hi");
    return 0;
}

Теоретически это полезная функция;Вы можете наблюдать сложное выражение, ломающееся, как только оно ложное, что-то вроде постоянно проверяемого утверждения.Например, вы можете watch a==b в вышеуказанной программе.

На практике это неожиданно, часто вызывает эту проблему, и обычно это не то, что вам нужно.

Чтобы смотреть только цельадрес, используйте watch -location itrap_t_beg[1][222].(Это доступно для GDB 7.3, выпущенной в июле 2011 года; если вы все еще используете 7.1, используйте print &itrap_t_beg[1][222] и watch *(itrap_t)0x12345678 или любой другой адрес, который он печатает.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...