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

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

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

Чтобы уточнить, вот пример из info break:

(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x08048517 <foo::bar(void)+7>

person casualcoder    schedule 01.02.2009    source источник


Ответы (11)


Начиная с GDB 7.2 (23.08.2011) теперь вы можете использовать сохранить точки останова.

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> для восстановления сохраненных точек останова из файла.

person aculich    schedule 21.10.2010
comment
как насчет того, если они из общей загрузки библиотеки? По умолчанию отвечает N кажется ... Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal] - person bjackfly; 24.01.2014
comment
comment
Обратите внимание, что если у вас есть условие точки останова, которое не может быть разрешено при запуске (break g_log if log_level==G_LOG_LEVEL_CRITICAL), то по крайней мере gdb 7.8.1 прекратит синтаксический анализ дальнейших команд. Если у вас есть дополнительные команды, которые должны быть выполнены для этой точки останова, поместите строку commands перед строкой condition. - person Lekensteyn; 19.12.2014
comment
@Andry Я откатил вашу правку к моей исходной цитате, потому что текст является дословной цитатой из документации ... В противном случае я бы согласился с вашим редактированием, если бы это были мои собственные слова. - person aculich; 13.01.2015
comment
@aculich: Понятно. Я бы рекомендовал в любом случае использовать стиль цитирования, а не стиль кода. - person Andry; 13.01.2015
comment
.Gdbinit не работает с 'cgdb', поэтому меня устраивает явное 'сохранить точки останова /tmp/pointbreak.dbg' и его противоположность 'source /tmp/pointbreak.dbg' - person eigenfield; 05.05.2017

Этот ответ устарел. 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
person Johannes Schaub - litb    schedule 01.02.2009
comment
Можно было бы так же легко использовать «вырезать и вставить», но метод сценариев, похоже, подходит. - person casualcoder; 01.02.2009
comment
я не думаю, что вырезать и вставить проще, чем просто написать скрипт один раз, а затем использовать его каждый раз снова :) в конце концов, я думаю, именно поэтому вы задали этот вопрос в первую очередь :) - person Johannes Schaub - litb; 01.02.2009
comment
Гм, я имел в виду использование вырезания и вставки вместо метода регистрации. Скриптинг - это пока точно. - person casualcoder; 02.02.2009
comment
Ух ты! GDB Fail! Я использую его каждый день и мне нравятся многие его функции. Но недостаток просто тупой. - person deft_code; 11.09.2009
comment
Этому ответу уже более двух лет, поэтому он может быть устаревшим, если вы используете более новую версию gdb. Начиная с gdb 7.2, теперь вы можете использовать команду save breakpoints. - person aculich; 03.02.2011
comment
Этот ответ по-прежнему полезен для тех из нас, кому нужно работать с устаревшими системами. - person mMontu; 25.06.2014

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

person Paul Beckingham    schedule 01.02.2009
comment
На самом деле это не работает, я получаю предупреждение: save-tracepoints: нет точек трассировки для сохранения. И это несмотря на то, что установлены точки останова. Использование gdb 6.8. - person casualcoder; 24.07.2010
comment
У меня это работает. GDB необходимо наличие глобального .gdbinit в вашем $ HOME / .gdbinit с содержимым 'add-auto-load-safe-path /home/johnny/src/.gdbinit', и, следовательно, папка src / также имеет отдельный .gdbinit - person eigenfield; 05.05.2017

Расширение анонимного расширения до Ответ Йоханнеса:

.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.

person Dan Berindei    schedule 27.05.2010
comment
Вот более подходящее регулярное выражение: perl -ne print \ break \ $ 1 \ n \ if /at\s(.*:\d+)/ brestore.txt - person George Godik; 21.09.2011

Расширение ответ Йоханнеса: вы может автоматически переформатировать вывод 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 (Кармическая коала).

person Community    schedule 09.02.2010
comment
Спасибо за этот фрагмент! Работает отлично. Успешно протестирован с 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. - person pestophagous; 18.02.2010

Возможно это:

save breakpoints [filename]

person Abel    schedule 19.07.2010
comment
Это уже было рассмотрено в принятом ответе. - person Peter Mortensen; 01.12.2019

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

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end
person badeip    schedule 27.08.2013

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

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

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

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

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

  • Сохраните точки останова: 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
person Mark A    schedule 04.10.2016

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

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

person Michael Snyder    schedule 28.10.2009

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

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
person noisy    schedule 01.07.2010