Игнорируйте, но учитывайте попадание точек останова в lldb/gdb

#gdb #lldb

Вопрос:

У меня есть две точки останова A и B . И я хотел бы подсчитать, сколько случаев A произойдет до B того, как будет нанесен удар. Дело в том, что это A происходит довольно часто (>1000), поэтому я не могу вручную продолжать и повторять. A также может произойти после B , поэтому я не могу запустить программу до завершения, чтобы узнать количество попаданий. Есть ли автоматический способ сделать это?

Ответ №1:

Вы можете сделать это довольно легко с помощью точки останова автоматического продолжения в точке A и команд в точке останова B. В простейшем подходе точка останова на A будет выглядеть так:

 break set <HoweverYouSpecifyA> --auto-continue 1 -N BreakpointA
 

Тогда точка останова на B будет:

 break set <HoweverYouSpecifyB> -C "break list BreakpointA" -C "break disable BreakpointA" --one-shot
 

На break list BreakpointA выходе будет показано количество попаданий A, когда вы нажмете B, что вы и хотели знать. Отключив A, когда вы нажмете B, количество попаданий для A останется таким же, каким оно было, когда вы нажмете B, поэтому вы сможете проверить его в любой момент после этого (до повторного запуска).

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

Я также сделал точку останова B одноразовой, так как вы просто используете ее, чтобы заморозить количество попаданий A, поэтому ей нужно попасть только один раз. Если это более удобно, вы также можете заставить B автоматически продолжить, а затем просто считывать количество попаданий A при выходе из программы.

Если бы вы хотели стать более модным, вы могли бы вместо этого использовать обратный вызов Python для B, получить количество попаданий от A и сообщить об этом так, как вы хотите. Это больше работы, но легче управлять форматированием вывода с Python…

Ответ №2:

Есть ли автоматический способ сделать это?

В GDB я обычно делаю это:

 (gdb) ign 1 10000
(gdb) cont
 

Когда будет достигнута вторая (B) точка останова, info break скажет что-то вроде:

 (gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000555555555129 in a at t.c:1
        breakpoint already hit 1234 times                         <<<===
        ignore next 8766 hits
2       breakpoint     keep y   0x0000555555555130 in b at t.c:2
        breakpoint already hit 1 time
 

Если 10000 окажется недостаточно, вы всегда можете увеличить его до 10000000 вместо этого.

Комментарии:

1. Не можете ли вы сделать то же самое, добавив команду «продолжить» к первой точке останова? Таким образом, вам не придется угадывать максимальное количество попаданий.

2. @JimIngham, Вы могли бы, но это, скорее всего, медленнее (хотя я не измерял это). С ignore помощью GDB не нужно оценивать вложенную команду.

3. Если gdb сможет справиться с остановкой достаточно быстро, чтобы одна команда «продолжить» поднялась над шумом, я был бы либо сильно впечатлен ее эффективностью (или, к сожалению, разочарован производительностью интерпретатора команд). Тем не менее, прошло несколько десятилетий с тех пор, как я в последний раз работал над gdb, поэтому в наши дни я не очень хорошо понимаю его производительность.