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

100

Моя цель:

  • Учитывая приостановленный поток в 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 и есть ли какие-либо образцы кода, которые загружают локальные переменные?"

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

  • 2
    На самом деле я не использовал JCL-модули Jedi для доступа к информации TD32 - для этого у меня есть собственная проприетарная библиотека, но, похоже, вся необходимая вам сантехника есть в JclTD32.pas. Тем не менее, я не могу найти демонстрационный код для доступа к информации о переменных, но пример, который там есть (в .. \ jcl \ examples \ windows \ debug \ sourceloc), показывает, как получить информацию о номере строки из данных TD32, поэтому Вы должны быть в состоянии опираться на это, чтобы получить то, что вам нужно. Пожалуйста, сообщите здесь, что вы узнали :)
  • 2
    @ 500-InternalServerError Спасибо. Информация о номере строки проста (даже в файлах карты) - но можете ли вы предоставить какую-либо информацию о том, что вы видите в коде JCL, которая конкретно относится к локальным символам? Кроме того, из любопытства, что является вашей собственной библиотекой TD32, и является ли она опубликованной / общедоступной или только для внутреннего использования?
Показать ещё 6 комментариев
Теги:
stack
local-variables
debug-symbols

1 ответ

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

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?
  • 0
    @ ДэвидМ, ваш комментарий очень важен. Попробуйте найти порт GNU Binutils или GNU Debugger в Windows (я знаю только порт Binutils). Есть библиотека BFD для GDB. Используется также в Binutils. Это позволяет читать несколько форматов файлов и распознавать их по магическим номерам. Если все не удается, используйте инструмент под названием strings . Он извлечет строки из любого двоичного файла. Смотрите справочную страницу . Это напечатает строки, которые могут, но не должны быть полезными

Ещё вопросы

Сообщество Overcoder
Наверх
Меню