GDB: выполняется до определенной точки останова

В GDB отладке кода С++: у меня есть 15 точек останова стратегически, но я не хочу, чтобы кто-либо из них активировался до тех пор, пока я не ударил точку останова # 2. Есть ли в GDB команда run-until-breakpoint-n?

Я считаю, что я делаю одну из двух вещей:

  • Удалите все остальные точки останова, так что # 2 - это все, что существует, запустите, повторно добавьте все точки останова; или

  • Запуск и повторение continue за все разрывы, пока я не увижу первый разрыв на # 2.

Я хочу что-то вроде run-until 2, которое будет игнорировать все остальные точки останова, кроме # 2, но не удалять их. Это существует? У кого-нибудь еще есть лучший способ справиться с этим?

Ответ 1

Начиная с версии 7.0 GDB поддерживает скрипты python. Я написал простой script, который временно отключит все включенные точки останова, кроме одного с указанным номером, и выполнит команду GDB run.

Добавьте следующий код в файл .gdbinit:

python
import gdb

class RunUntilCommand(gdb.Command):
    """Run until breakpoint and temporary disable other ones"""

    def __init__ (self):
        super(RunUntilCommand, self).__init__ ("run-until",
                                               gdb.COMMAND_BREAKPOINTS)

    def invoke(self, bp_num, from_tty):
        try:
            bp_num = int(bp_num)
        except (TypeError, ValueError):
            print "Enter breakpoint number as argument."
            return

        all_breakpoints = gdb.breakpoints() or []
        breakpoints = [b for b in all_breakpoints
                       if b.is_valid() and b.enabled and b.number != bp_num and
                       b.visible == gdb.BP_BREAKPOINT]

        for b in breakpoints:
            b.enabled = False

        gdb.execute("run")

        for b in breakpoints:
            b.enabled = True

RunUntilCommand()
end

Ответ 2

Вы можете enable и disable точки останова, и эти команды будут принимать диапазон. Используйте эти команды с диапазоном в стратегических точках во время выполнения программы.

Я предполагаю, что когда вы упоминаете точку останова № 2, вы имеете в виду нумерацию точек останова gdb. Вот простой пример сеанса gdb:

(gdb) info breakpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x00001ddb in main at example.c:34
2   breakpoint     keep y   0x00001e00 in main at example.c:39
3   breakpoint     keep y   0x00001e15 in main at example.c:40
(gdb) disable 1-3
(gdb) enable 2
(gdb) info breakpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep n   0x00001ddb in main at example.c:34
2   breakpoint     keep y   0x00001e00 in main at example.c:39
3   breakpoint     keep n   0x00001e15 in main at example.c:40
(gdb) 

Теперь включена только точка останова # 2. Запустите программу, и когда выполнение прерывается на # 2, повторно включите все ваши искомые точки останова с диапазоном:

(gdb) enable 1-3
(gdb) info breakpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x00001ddb in main at example.c:34
2   breakpoint     keep y   0x00001e00 in main at example.c:39
3   breakpoint     keep y   0x00001e15 in main at example.c:40

Вы также можете смешивать номера и диапазоны контрольных точек:

(gdb) disable 1 4 6-7
(gdb) info breakpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep n   0x00001ddb in main at example.c:34
2   breakpoint     keep y   0x00001e00 in main at example.c:39
3   breakpoint     keep y   0x00001e15 in main at example.c:40
4   breakpoint     keep n   0x00001e4f in main at example.c:43
5   breakpoint     keep y   0x00001e4f in main at example.c:44
6   breakpoint     keep n   0x00001e5e in main at example.c:45
7   breakpoint     keep n   0x00001e5e in main at example.c:46

Ответ 3

Чуть менее болезненным, чем удаление всех остальных точек останова, будет disable их. Таким образом, вам не нужно повторно вводить все элементы, связанные с точкой останова, чтобы вернуть их, просто enable снова по номеру.

Ответ 4

С gdb точки останова могут быть отключены, а не удалены. Тогда все, что вам нужно сделать, - это снова использовать их при необходимости.