Заставить GDB сохранить список точек останова

129

Хорошо, info break перечисляет точки останова, но не в формате, который бы хорошо работал с их повторным использованием с помощью команды --command, как в этом вопросе . Есть ли у GDB способ снова сбросить их в файл, приемлемый для ввода? Иногда в сеансе отладки необходимо перезапустить GDB после создания набора точек останова для тестирования.

Файл .gdbinit имеет ту же проблему, что и --command. Команда info break не выводит список команд, а представляет собой таблицу для использования человеком.

Чтобы уточнить, вот образец информационного перерыва :

(gdb) информационная пауза
Num Type Disp Enb Address What
1 точка останова сохранить y 0x08048517 <foo :: bar (void) +7>
casualcoder
источник

Ответы:

204

Начиная с GDB 7.2 (2011-08-23) теперь вы можете использовать команду сохранения точек останова .

save breakpoints <filename>
  Save all current breakpoint definitions to a file suitable for use
  in a later debugging session.  To read the saved breakpoint
  definitions, use the `source' command.

Используйте source <filename>для восстановления сохраненных точек останова из файла.

aculich
источник
2
как насчет того, если они из общей загрузки библиотеки? По умолчанию он отвечает N, кажется ...Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
bjackfly
Обратите внимание, что когда у вас есть условие точки останова, которое не может быть разрешено при запуске ( break g_log if log_level==G_LOG_LEVEL_CRITICAL), по крайней мере, gdb 7.8.1 прекратит синтаксический анализ дальнейших команд. Если у вас есть дополнительные команды, которые должны быть выполнены для этой точки останова, поместите commandsстроку перед conditionстрокой.
Lekensteyn
@Andry Я откатил вашу правку к моей исходной цитате, потому что текст является дословной цитатой из документации ... В противном случае я бы согласился с вашим редактированием, если бы это были мои собственные слова.
aculich
@aculich: Понятно. Я бы рекомендовал в любом случае использовать стиль цитирования, а не стиль кода.
Andry
26

Этот ответ устарел. GDB теперь поддерживает сохранение напрямую. Смотрите этот ответ .

Вы можете использовать ведение журнала:

(gdb) b main
Breakpoint 1 at 0x8049329
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>
(gdb) set logging file breaks.txt
(gdb) set logging on
Copying output to breaks.txt.
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>
(gdb) q

Теперь файл breaks.txt содержит:

Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>

Написать сценарий AWK, преобразующий его в формат, полезный для файла .gdbinitили --command, легко. Или вы можете даже сделать так, чтобы сценарий выдавал отдельные --eval-commandсимволы в командной строке GDB ...

Добавление этого небольшого макроса в .gdbinit поможет вам в этом:

# Call with dump_breaks file.txt
define dump_breaks
    set logging file $arg0
    set logging redirect on
    set logging on
    info breakpoints
    set logging off
    set logging redirect off
end
Йоханнес Шауб - litb
источник
Можно было бы так же легко использовать «вырезать и вставить», но метод сценариев, похоже, подходит.
casualcoder, 01
1
Я не думаю, что вырезать и вставить проще, чем просто написать сценарий один раз, а затем использовать его каждый раз снова :) в конце концов, я думаю, именно поэтому вы и задали этот вопрос в первую очередь :)
Йоханнес Schaub -
Гм, я имел в виду использование вырезания и вставки вместо метода регистрации. Скриптинг - это пока точно.
casualcoder, 01
Вот Это Да! gdb fail! Я использую его каждый день и люблю многие его функции. Но недостаток - это просто глупо.
deft_code
4
Этому ответу уже более 2 лет, поэтому он может быть устаревшим, если вы используете более новую версию gdb. Начиная с gdb 7.2, теперь вы можете использовать save breakpointsкоманду.
aculich 03
11

Поместите ваши команды GDB и точки останова в файл .gdbinit так же, как вы могли бы ввести их в команднойgdb> строке, и GDB автоматически загрузит и запустит их при запуске. Это файл для каждого каталога, поэтому у вас могут быть разные файлы для разных проектов.

Пол Бекингем
источник
1
На самом деле это не работает, я получаю предупреждение: save-tracepoints: нет точек трассировки для сохранения. И это несмотря на то, что точки останова установлены. Используется gdb 6.8.
casualcoder
У меня это работает. GDB необходимо наличие глобального .gdbinit в вашем $ HOME / .gdbinit с содержимым 'add-auto-load-safe-path /home/johnny/src/.gdbinit' и, следовательно, в папке src / также есть отдельный .gdbinit
truthadjustr
9

Расширение расширения Анон в к ответу Йоханнеса :

.gdbinit:

define bsave
    shell rm -f brestore.txt
    set logging file brestore.txt
    set logging on
    info break
    set logging off
    # Reformat on-the-fly to a valid GDB command file
    shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
end
document bsave
  store actual breakpoints
end

define brestore
  source brestore.gdb
end
document brestore
  restore breakpoints saved by bsave
end

С помощью brestoreвы можете восстановить точки останова, сохраненные с помощью bsave.

Дэн Бериндей
источник
Вот более подходящее регулярное выражение: perl -ne "print \" break \ $ 1 \ n \ "if /at\s(.*:\d+)/" brestore.txt
Джордж Годик
6

Расширение ответа Йоханнеса : вы можете автоматически переформатировать вывод info breakв действительный командный файл GDB:

.gdbinit:

define bsave
   shell rm -f brestore.txt
   set logging file brestore.txt
   set logging on
   info break
   set logging off
   # Reformat on-the-fly to a valid gdb command file
   shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
end
document bsave
  store actual breakpoints
end

После этого у вас будет действующий командный файл в формате brestore.gdb.

У меня это сработало, когда приложение скомпилировано с -g.

Я также успешно протестировал его с GDB v6.8 на Ubuntu 9.10 (Karmic Koala).

Питер Мортенсен
источник
1
Спасибо за этот фрагмент! Прекрасно работает. Успешно протестирован с GNU gdb 6.3.50-20050815 (версия Apple gdb-966) в CarbonEmacs GNU Emacs 22.3.1 (i386-apple-darwin9.6.0, Carbon Version 1.6.0) в Mac OS 10.5.8.
пестофаги
3

Поместите следующее в ~ / .gdbinit, чтобы определить bsave и brestore как команды GDB для сохранения и восстановления точек останова.

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end
badeip
источник
1

предупреждение: текущий протокол вывода не поддерживает перенаправление

Я также получаю эту ошибку / предупреждение в GDB при попытке включить ведение журнала в режиме TUI . Однако ведение журнала, похоже, работает в режиме "без TUI". Поэтому я выхожу из режима TUI всякий раз, когда хочу что-то записать. (Переключайтесь назад и вперед в режим TUI с помощью Ctrl+X , Ctrl+A ).

Вот как я работаю:

  1. запустить GDB (в обычном режиме)
  2. включить логирование: set logging on- теперь жаловаться не должно.
  3. переключаться назад / вперед в режим TUI и делать вещи GDB
  4. всякий раз, когда я хочу что-то записать (например, огромный дамп обратной трассировки) - переключитесь в нормальный режим
Magnux
источник
Да, и если вам нравится использовать «экран» (как я), он будет немного запутанным, так как он использует те же горячие клавиши.
Magnux
1

Я нашел следующее дополнение к предыдущему ответу полезным для сохранения / загрузки точек останова в конкретный файл.

  • Сохранить точки останова: bsave {filename}
  • Загрузить точки останова: bload {filename}

Как и в предыдущем ответе, добавьте следующий код в файл ~ / .gdbinit

# Save breakpoints to a file
define bsave
    if $argc != 1
        help bsave
    else
    save breakpoints $arg0
    end
end
document bsave
Saves all current defined breakpoints to the defined file in the PWD
Usage: bsave <filename>
end

# Loads breakpoints from a file
define bload
    if $argc != 1
        help bload
    else
        source $arg0
    end
end
document bload
Loads all breakpoints from the defined file in the PWD
Usage: bload <filename>
end
Марк А
источник
0

Проблема в том, что установка точки останова зависит от контекста. Что делать, если у вас есть две статические функции с именем foo ?

Если вы уже отлаживаете один из модулей, определяющих foo, то GDB предположит, что вы имели в виду именно этот. Но если вы просто скопируете «break foo» в файл, а затем прочитаете этот файл при запуске, не будет ясно, какую функцию foo вы имеете в виду.

Майкл Снайдер
источник
0

Есть другие идеи? у меня есть

warning: Current output protocol does not support redirection

после

set logging on

РЕДАКТИРОВАТЬ:

Я знаю, что вопрос в том, «как сохранить список точек останова», однако я только что обнаружил, что с помощью GDB мы можем просто установить точки останова «сохраненные в файле»

gdb> source breakpoints.txt

где breakpoints.txtтакой файл:

break main.cpp:25
break engine.cpp:465
break wheel.cpp:57
шумный
источник