Як витягуєте інформацію про локальну змінну (адресу та тип) з програми Delphi або інформації про налагодження, створеної компілятором?


105

Моя мета:

  • З огляду на підвішений потік 32-ти або 64-розрядної програми Windows, складеної Delphi, для проходження стека (виконання)
  • Дано записи стеків для перерахування локальних змінних у кожному методі та їх значень. Тобто, принаймні, знайдіть їх адресу та тип (integer32 / 64 / підписаний / неподписаний, рядок, плаваючий, запис, клас ...), поєднання яких можна використовувати для пошуку їх значення.

Перше - це добре, і це друге питання. На високому рівні, як ви перераховуєте локальні змінні, що мають запис стека в Delphi?


На низькому рівні я це досліджував:

RTTI: не перераховує такого роду інформацію про методи. Це було не те, що я насправді коли-небудь вважав реалістичним варіантом, але перелік тут все одно.

Інформація про налагодження : завантажується інформація про налагодження, створена для складання налагодження.

  • Файли з картою: навіть детальний файл карти (файл у текстовому форматі! Відкрийте один і подивіться) не містить локальної інформації про змінну. Це в основному список адрес і номерів рядків вихідних файлів. Чудово підходить для співвідношення файлів і ліній, наприклад, сині точки в жолобі; не чудово для більш детальної інформації
  • Інформація про віддалену налагодження (файл RSM) - невідома інформація про її вміст чи формат.
  • Файли TD32 / TDS: мій поточний напрямок досліджень. Вони містять глобальну та локальну символіку серед безлічі іншої інформації.

Проблеми, з якими я стикаюся тут:

  • Немає документації щодо формату файлів TD32 (яку я можу знайти.)
  • Більшість моїх знань про них походить з коду JCL Jedi, що використовує їх (JclTD32.pas), і я не впевнений, як використовувати цей код, або чи є структури там достатньо обширними, щоб показувати місцеві зміни. Я впевнений, що він буде працювати з глобальними символами, але я дуже не впевнений у місцевих. Існує велика кількість констант, визначених і без документації для формату, щоб прочитати, що вони означають, я залишаюсь здогадуватися. Однак ці константи та їхні назви мають десь походити.
  • Джерело, яке я можу знайти, використовуючи інформацію про TDS , не завантажує та не обробляє локальні символи.

Якщо це правильний підхід, тоді це питання стає "Чи є документація для формату файлів TDS / TD32, і чи є зразки коду, які завантажують локальні змінні?"

Зразок коду не є важливим, але може бути дуже корисним, навіть якщо він дуже мінімальний.


2
Насправді я не використовував підрозділи JCL JDL для доступу до інформації про TD32 - у мене є своя власна бібліотека для цього, але це схоже на всі основні сантехніки, які вам знадобляться, є в JclTD32.pas. Немає демо-коду, який я можу знайти для доступу до змінної інформації, але зразок, який є там (у .. \ jcl \ example \ windows \ debug \ sourceloc) показує, як отримати інформацію про номер рядка з даних TD32, так ви повинні мати можливість спиратися на те, щоб отримати те, що вам потрібно. Будь ласка, повідомте про те, що ви дізнаєтесь :)
500 - Помилка внутрішнього сервера

2
@ 500-InternalServerError Спасибі Інформація про номер рядка проста (є навіть у файлах карт) - але чи можете ви надати будь-яку інформацію про те, що ви бачите в коді JCL, яка спеціально стосується локальних символів? Крім того, з цікавості, що є власною власною бібліотекою TD32, і чи видана вона / доступна для публічного використання або лише внутрішня?
Девід

3
Кожен символ процедури / функції / методу під ним містить перелік символів, які є для нього локальними. Здається, більшість визначень є в підрозділі джедаїв, але деякі є коментарями. Моєю пропозицією було б створити крихітні тестові програми та подивитися, що повертається перерахування символів. Код, який я маю, є власником і не публікується для мене. Це все одно не висвітлює тему локальних змінних. Але інформація, на якій ґрунтується, є напівдоступною, тому я можу вам допомогти, якщо ви натрапите на конкретні стіни.
500 - Внутрішня помилка сервера

4
tds2pdb ( code.google.com/p/map2dbg ), схоже, має аналізатор файлів tds. Це все-таки C # код.
Graymatter

4
Так, раніше був неофіційний документ, але тоді Borland (на той час) вирішив випустити dll замість доступу до інформації про налагодження, щоб вони могли змінити внутрішній формат і не потребувати оновлення документації. На жаль, зараз я не можу знайти ні оригінальний документ, ні dll. Я пропоную вам звернутися в службу технічної підтримки Embarcadero і запитати про це.
500 - Внутрішня помилка сервера

Відповіді:


2

Перевірте, чи будь-які символи налагодження не були у двійкових. Можливо також використання GDB (в Windows його порт). Було б чудово, якби ви знайшли .dbg або .dSYM файл. Вони містять вихідний код, наприклад.

gdb> list foo
56 void foo()
57 {
58  bar();
59  sighandler_t fnc = signal(SIGHUP, SIG_IGN);
60  raise(SIGHUP);
61  signal(SIGHUP, fnc);
62  baz(fnc);
63 }

Якщо у вас немає файлів налагодження, ви можете спробувати отримати MinGW або Cygwin і скористатися nm (1) ( man page ). Він буде читати імена символів з двійкових. Вони можуть містити деякі типи, як-от C ++:

int abc::def::Ghi::jkl(const std::string, int, const void*)

--demangleТоді не забудьте додати варіант, або ви отримаєте щось на кшталт:

__ZN11MRasterFont21getRasterForCharacterEh

замість:

MRasterFont::getRasterForCharacter(unsigned char)

2
Якуб, дякую за відповідь. На жаль, мені, мабуть, потрібно прочитати певний формат налагодження - TDS. Програми Delphi не компілюються з інформацією про налагодження, сумісною з GDB, у Windows. Я не впевнений, як nm допоможе, оскільки він буде покладатися на певний формат файлу налагодження, який, мабуть, не такий, який створює Delphi. Або я неправильно зрозумів вашу відповідь - чи може GDB читати символи Delphi, наприклад?
Девід

@DavidM, ваш коментар дуже важливий. Спробуйте знайти порт GNU Binutils або GNU Debugger у Windows (я знаю лише порт Binutils). Існує бібліотека BFD для GDB. Він використовується також у Бінутілсі. Це дозволяє читати кілька форматів файлів і розпізнавати їх за їх магічними номерами. Якщо все не вдається, скористайтеся інструментом під назвою strings. Він буде витягувати рядки з будь-якого двійкового файлу. Див. Сторінку чоловіка . Це надрукує рядки, які можуть, але не повинні бути корисними
Вгору Секрет

0

Погляньте на http://download.xskernel.org/docs/file%20formats/omf/borland.txt Посібник з відкритої архітектури. Він старий, але, можливо, ви знайдете релевантну інформацію про формат файлу.


Чи можете ви, будь ласка, додали якийсь контекст, в майбутньому посилання може розірватися.
Hintham

Посилання містить офіційний документ від borland про формат файлу OMF, який використовується компілятором Borland та іншими форматами бінарних файлів, які використовує Borland. Деякі роки тому я подивився на формат файлу TDS і, здавалося, деякі частини сумісні з документально підтвердженими форматами файлів. Намагаючись зібрати будь-яку інформацію про локальні змінні з файлу TDS, слід використовувати зв'язану документацію або посилатися на неї. Якщо посилання буде розірвано, моя відповідь буде марною, і потрібна інформація буде втрачена. Пов'язаний "Посібник з відкритої архітектури" був частиною старих випусків Turbo Pascal та C.
Muetze1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.