Чому GDB потребує виконуваного файлу, а також основного дампа?


11

Я налагоджую за допомогою основних дампів і зауважую, що gdb потребує вас, щоб поставити виконуваний файл, а також основний дамп. Чому це? Якщо основний дамп містить всю пам'ять, яку використовує процес, чи не виконаний файл, який міститься в дампі ядра? Можливо, немає гарантії того, що весь exe завантажений у пам'ять (окремі виконувані файли, як правило, не такі великі), або, можливо, основний дамп не містить усієї відповідної пам'яті? Це для символів (можливо, вони нормально не завантажуються в пам'ять)?


1
Виконавчий файл містить інформацію про символи, як зазначено в документації на gdb ...
Томас Дікі

1
Дивно, але жодна відповідь (крім тієї, яку я щойно додав) згадує формат DWARF
Базиль Старинкевич

Відповіді:


15

Основний дамп - це лише дамп пам'яті програми вашої програми, якщо ви знаєте, де все було, то можете просто використовувати це.

Ви використовуєте виконуваний файл, оскільки він пояснює, де (з точки зору логічних адрес) речі знаходяться в пам'яті, тобто основний файл.

Якщо ви використовуєте команду, objdumpвона скидає метадані про виконуваний об’єкт, який ви досліджуєте. Використання виконавчого об'єкта з ім'ям a.out в якості прикладу.

objdump -h a.outскидає лише інформацію заголовка, ви побачите розділи, названі напр. .data або .bss або .text (є ще багато). Вони інформують завантажувач ядра, де в об'єкті можуть бути знайдені різні розділи та де в адресному просторі процесу розділ повинен бути завантажений, а для деяких розділів (наприклад, .data .text), що слід завантажувати. (.bss розділ не містить жодних даних у файлі, але він стосується обсягу пам'яті, який потрібно резервувати в процесі неініціалізованих даних, він заповнюється нулями).

Макет виконавчого об'єктного файлу відповідає стандарту, ELF.

objdump -x a.out - скидає все

Якщо виконуваний об'єкт все ще містить таблиці символів (він не був знятий - man stripі ви використовували -gдля генерації налагодження до gcc припущення компіляції джерела змінного струму), то ви можете вивчити основний вміст за іменами символів, наприклад, якщо у вас була змінна / буфер названий inputLine у своєму вихідному коді, ви можете використовувати це ім'я gdbдля перегляду його вмісту. тобто gdbзнає зміщення від початку ваших програм ініціалізованого сегмента даних, де починається inputLine та довжина цієї змінної.

Подальше читання Article1 , стаття 2 , і вошивий піщаний Виконувані і Linking Format (ELF) специфікації .


Оновлення після коментаря @mirabilos нижче.

Але якщо використовувати таблицю символів як в

$ gdb --batch -s a.out -c core -q -ex "x buf1"

Виробляє

 0x601060 <buf1>:    0x72617453

а потім не використовувати таблицю символів та досліджувати адресу безпосередньо в,

$ gdb --batch -c core -q -ex "x 0x601060"

Виробляє

0x601060:   0x72617453

Я вивчив пам'ять безпосередньо, не використовуючи таблицю символів у 2-й команді.


Я також бачу, що відповідь @ user580082 додає додаткові пояснення, і буде голосувати під голосом.


6
Ніколи не чув про "основний розділ стека". .bss (історично) "блок, запущений символом" і практично, "неіціалізовані дані", а .data - "ініціалізовані дані", а текст (не. код) використовується для зберігання машинного коду. У двійковому файлі немає розділу стека, оскільки стеки створюються під час виконання.
jlliagre

"Якщо ви знаєте, де все було, то можете просто скористатися цим", це неправда, тому що не все в програмі обов'язково включається в слід.
mirabilos

1
@jlliagre ви праві, я помилково назвав .text .code (тому що я думав про пояснення під час складання відповіді) - оновлено. Я помилково подумав про те, що Bss неправильно назвав, і оновив свою відповідь, але уникнув * Block Started by Symbol, оскільки я не думаю, що він дійсно додає рівняння, і пояснив, що він використовується як неініціалізовані дані, що було нашим загальне розуміння. Дякую - я оцінив ваш коментар, щоб виправити цю публікацію.
X Tian

4

Основний файл - це знімок зображення стека, відображення пам'яті та регістрів на час завершення процесу. Змістом якого можна керувати, як наведено на основній сторінці man man . За замовчуванням приватні відображення, спільні відображення та інформація заголовка ELF скидається в основний файл.

Приходячи до вашого запитання , причина, по якій gdb вимагає виконуваного файлу, полягає в тому, що він не імітує виконання, читаючи та інтерпретуючи двійкові інструкції, як, наприклад, valgrind, він стає батьківським процесом, щоб контролювати поведінку процесу під час запуску. час. Він використовує основний файл для визначення відображень пам'яті та стану процесора під час збоїв.

У батьківських процесах Linux можна отримати додаткову інформацію про своїх дітей, зокрема можливість відстежувати їх, що дозволяє налагоджувачу отримувати доступ до інформації низького рівня процесу, наприклад, читати / записувати його пам'ять, регістри, змінювати відображення сигналів, зупиняти його виконання тощо.

Ви зрозумієте вимогу виконуваного файлу, незважаючи на наявність основного файлу більше, коли ви прочитаєте, як працює будь-який налагоджувач.


1

(крім інших хороших відповідей)

У сучасних системах Linux (і багатьох Unix-подібних) інформація про налагодження (включаючи метадані про типи символів, розташування вихідного коду, тип змінних тощо тощо) складається у форматі DWARF і розташовується всередині виконуваного файлу ELF ( або спільні бібліотеки ELF), коли вона компілюється з деякою -gопцією. Я рекомендую компілювати програми для налагодження -g3 -O0і, можливо, -fno-inlineякщо використовувати недавній GCC ; однак, за допомогою GCC ви навіть можете компілювати інформацію як про оптимізацію, так і про налагодження, наприклад, за допомогою -O2 -g1, хоча інформація про налагодження в цьому випадку може бути дещо нечіткою (це може трохи допомогти зловити деяких неслухняних Heisenbugs ).

Цілком розумно уникати введення цієї інформації в основні файли, оскільки у вас може бути багато різних основних файлів (уявіть, що широко використовуване програмне забезпечення з багатьма користувачами, які роблять звіти про помилки, більшість з яких має coreдамп) для одного і того ж виконуваного файлу. Також ядро (5) файлів завантажується ядром, що не повинно піклуватися про існування секцій DWARF у виконуваних файлах elf (5) (оскільки ці розділи не відображаються у віртуальний адресний простір несправного процесу, який скидав ядро ​​на якийсь сигнал ( 7) ). Існує навіть можливість розміщення інформації про налагодження в окремих файлах (поза виконуваним файлом).

BTW, GDB можна болюче використовувати для налагодження ядерних відвалів для виконуваних файлів без будь-якої інформації про налагодження. Але тоді ви практично налагоджуєте на рівні машинного коду (не на символічному рівні, що надається мовами програмування та їх компіляторами).

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