Отримання GDB для збереження списку точок прориву


129

Гаразд, інформаційний перерв перераховує точки перерви , але не у форматі, який би добре працював з повторним використанням їх за допомогою --command, як у цьому питанні . Чи має метод GDB знову скинути їх у файл, прийнятний для введення? Іноді під час сеансу налагодження необхідно перезапустити GDB після створення набору точок перерви для тестування.

Файл .gdbinit має таку ж проблему, що і --command. Команда перерви інформації не містить команди, а скоріше таблицю для споживання людиною.

Щоб уточнити, ось приклад з інформаційного перерви :

(gdb) перерва інформації
Число типу Disp Enb Адреса Що
1 точка розриву тримати y 0x08048517 <foo :: bar (void) +7>

Відповіді:


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>для відновлення збережених точок зупинки з файлу.


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рядком.
Лекенштейн

@Andry Я повернув вашу редакцію до моєї оригінальної цитати, оскільки текст є дослівною цитатою з документації ... Я б інакше погодився з вашою редакцією, якби це були мої власні слова.
aculich

@aculich: Я бачу. Я б рекомендував використовувати стиль цитування, а не стиль коду в будь-якому випадку.
Андрій

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

Тепер файл.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

Можна було б так само легко використовувати вирізати і вставляти, але, мабуть, спосіб створення сценаріїв.
casualcoder

1
я не думаю, що вирізати і вставити простіше, ніж просто написати сценарій один раз, а потім використовувати його кожен раз знову :) зрештою, це була саме причина, коли ви задавали це питання в першу чергу, я думаю :)
Йоханнес Шауб - ліб

Гм, я мав на увазі використовувати вирізати і вставити замість методу ведення журналу. Сценарій це поки що точно.
casualcoder

Оце Так! gdb не вдалося! Я використовую її щодня і люблю багато її особливостей. Але нестача - це просто звичайний німий.
deft_code

4
Цій відповіді зараз більше 2 років, тому вона може бути застарілою, якщо ви використовуєте більш нову версію gdb. Станом на gdb 7.2 тепер ви можете використовувати save breakpointsкоманду.
aculich

11

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


1
Це фактично не спрацьовує, я отримую "попередження: save-tracepoints: немає жодних точок збереження". Це, незважаючи на встановлення точок
перерви

Це працює для мене. 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
George

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

1

попередження: Поточний вихідний протокол не підтримує перенаправлення

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

Ось як я працюю:

  1. запустити GDB (у звичайному режимі)
  2. включити ведення журналу: set logging on- тепер він не повинен скаржитися.
  3. перемикання назад / вперед до режиму TUI і виконувати GDB
  4. всякий раз, коли мені хочеться щось зареєструвати (наприклад, величезний зворотний дамп) - перемкніть на звичайний режим

Так, і якщо вам подобається використовувати "екран" (як я), він стане трохи безладним, оскільки він використовує ті самі гарячі клавіші.
Магнукс

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.