2010-03-15 1 views
12

На большом приложении C, я установить аппаратную точку наблюдения на адрес памяти следующим образом:GDB аппаратная сторожевая точка очень медленная - почему?

(gdb) watch *0x12F5D58 
Hardware watchpoint 3: *0x12F5D58 

Как вы можете видеть, это аппаратная точка наблюдения, а не программное обеспечение, которое могло бы объяснить медлительность.

Теперь время работы приложения под отладчиком изменилось с менее чем десяти секунд до одного часа и подсчета. Точка наблюдения срабатывала три раза до этого момента, первый раз через 15 минут, когда страница памяти, содержащая адрес, была сделана читаемой sbrk. Разумеется, в течение этих 15 минут точка наблюдения должна была быть эффективной, поскольку страница памяти была недоступна? И это все еще не объясняет, почему это так медленно.

Платформа x86_64 и версия GDB является Ubuntu 9,10 пакет:

$ gdb --version 
GNU gdb (GDB) 7.0-ubuntu 
[...] 

и запас GDB 7.1 построен из источников:

$ gdb-7.1 --version 
GNU gdb (GDB) 7.1 

Заранее спасибо за любые идеи, как то, что может быть вызвать или как исправить/обойти его.

EDIT: убрана отливать

EDIT: GdB 7,1

+0

Всегда ли медленно работать под отладчиком или только когда у вас установлена ​​точка наблюдения? – Gabe

+1

Только с точкой наблюдения. –

ответ

5

У меня действительно были проблемы с аппаратными точками наблюдения в GDB 7.x.x., что неприемлемо, поскольку точки наблюдения являются необходимостью в моей работе.

По рекомендации соавтора я загрузил источник для 6.7.1 и построил его локально. Теперь точки наблюдения работают намного лучше.

Возможно стоит попробовать.

+0

Интересно. Я попробую это. –

+1

В GDB 6.7.1 отсутствует функция, в которой можно использовать точки наблюдения на адресе памяти, недоступные на время настройки точки наблюдения. Можно включить его в нужное время, но это будет более активно, я попробую позже. Я также попробовал только что выпущенный GDB 7.1, такую ​​же проблему, как и с 7.0. –

+0

с условными точками останова и командами останова, с которыми вы могли бы обойтись без особых проблем. – alesplin

4

Это скорее всего потому, что вы литья его каждый раз. Попробуйте это:

(gdb) watch *0x12F5D58 

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

(gdb) info break 

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

+0

Может gdb действительно разыменовать целочисленный литерал, не требуя знать, какой тип разыменовывается как? Это не допустимое выражение C, по крайней мере ... – unwind

+0

Да, это возможно. Я делаю это все время. –

+1

К моему удивлению (я думал, что GDB принимает только выражения C) «watch * 0x12F5DF8» работает, но работает так же медленно, как и предыдущая версия. –

1

На x86 у вас есть следующее ограничение: все ваши точки наблюдения могут охватывать не более четырех адресов памяти, каждый адрес памяти может следить за одним словом памяти - это потому, что аппаратные точки наблюдения (быстрые) используют регистры отладки процессоров , у вас их четыре, поэтому четыре места для наблюдения.

+1

Он уже сказал, что у него только одна точка наблюдения, см. Четвертый комментарий к ответу Натана. –

5

Я обнаружил, что просмотр большого символьного буфера был очень медленным, тогда как наблюдение за символом в этом буфере было очень быстрым.

например.

static char buf[1024]; 
static char* buf_address = &buf; 

watch buf_address - мучительно медленно.

watch *buf_address - очень быстро.

Смежные вопросы