Как вы извлекаете локальную информацию о переменных (адрес и тип) из программы Delphi или информацию об отладке, генерируемую компилятором?

Моя цель:

  • Учитывая приостановленный поток в Delphi-скомпилированной 32-разрядной или 64-разрядной программе Windows, чтобы выполнить стек (выполнимый)
  • Указанные записи стека, чтобы перечислять локальные переменные в каждом методе и их значения. То есть, по крайней мере, найдите их адрес и тип (integer32/64/signed/unsigned, string, float, record, class...), комбинация которых может быть использована для поиска их значения.

Первое прекрасно, а второе - это вопрос. На высоком уровне как вы перечисляете локальные переменные, учитывая запись стека в Delphi?


На низком уровне это то, что я изучал:

RTTI: не перечисляет такую ​​информацию о методах. Это было не то, что я когда-либо считал реалистичным вариантом, но перечисление здесь в любом случае.

Отладочная информация: Загрузка отладочной информации, созданной для сборки отладки.

  • Файлы карт: даже подробный файл карты (текстовый файл! Открыть и посмотреть) не содержит информации о локальной переменной. Это в основном список адресов и номеров строк исходного файла. Отлично подходит для корреляции адресов и файлов, например. синие точки в желобе; не подходит для более подробной информации
  • Информация о дистанционной отладочной информации (RSM файл) - неизвестная информация о ее содержании или формате.
  • Файлы TD32/TDS: моя текущая серия исследований. Они содержат глобальные и локальные символы среди множества других сведений.

Проблемы, с которыми я сталкиваюсь, следующие:

  • Нет документации файла формата TD32 (который я могу найти.)
  • Большинство моих знаний о них происходит из JED-кода Jedi, используя их (JclTD32.pas), и я не уверен, как использовать этот код, или структуры там достаточно обширны, чтобы показать локальные вары. Я вполне уверен, что он будет обрабатывать глобальные символы, но я не уверен в локальных. Существует множество разнообразных констант и без документации для формата, чтобы понять, что они означают, я угадал. Однако эти константы и их имена должны откуда-то появляться.
  • Источник, который я могу найти с помощью информации TDS, не загружает и не обрабатывает локальные символы.

Если это правильный подход, тогда возникает вопрос: "Имеется ли документация для формата файла TDS/TD32 и есть ли какие-либо образцы кода, которые загружают локальные переменные?"

Пример кода не является существенным, но может быть очень полезным, даже если он очень минимален.

Ответ 1

Проверьте, не были ли какие-либо символы отладки в двоичном формате. Также возможно использование 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). Он будет читать имена символов из двоичного кода. Они могут содержать некоторые типы, такие как С++:

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

Не забудьте добавить параметр --demangle, или вы получите что-то вроде:

__ZN11MRasterFont21getRasterForCharacterEh

вместо:

MRasterFont::getRasterForCharacter(unsigned char)