Формат MAP-файла, генерируемый компилятором или линкеро

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Alexey_Melky
новенький
Сообщения: 21
Зарегистрирован: 14.05.2005 14:55:31

Формат MAP-файла, генерируемый компилятором или линкеро

Сообщение Alexey_Melky »

FPC 2.2.0 + lazarus, собранный из текущей ветви 0.9.25.

Скомпилировал небольшой тестовый проект под Win32. При выполнении проекта было сгенерировано исключение.
Чтобы выяснить, где (в каком модуле, при выполнении какой строки кода) произошло исключение, попытался проанализировать и распарсить вручную MAP-файл, созданный компилятором или линкером. Обнаружил, что информация о модулях и строках не присутствует в этом файле.

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

Так, например map-файл, полученный при сборке проекта компилятором Delphi содержит исчерпывающую информацию о том, где именно искать код, вызвавший исключение. Мало того, имеется инструментарий, производящий автоматический парсинг такого MAP-файла и позволяющий наполнить содержательными данными callstack.
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

Может не в тему, но посмотрите в опциях компилятора->связывание - там есть возможность генерировать информацию о строках и для дебаггера... Тогда, по идее, сразу сам лазарус должен будет перейти на то место, где возникло исключение...
Alexey_Melky
новенький
Сообщения: 21
Зарегистрирован: 14.05.2005 14:55:31

Сообщение Alexey_Melky »

Brainenjii писал(а):Может не в тему, но посмотрите в опциях компилятора->связывание - там есть возможность генерировать информацию о строках и для дебаггера...

Если имеется ввиду опция -gl, то она включена. Тем не менее, повторюсь, что информация о строках нужна при выполнении программы на компе, где нет ни среды разработки, ни отладчика.

Для чего это нужно? Я собрал релиз некоего проекта, получил исполняемый файл, MAP-файл или какой-нибудь другой, описывающий соответствие адресов строкам исходных файлов. Исполняемый файл передается пользователям.

И, если возникает исключение у пользователя программы, программист, получив информацию об адресе, смог бы определить какая часть кода ответственна за произошедшее.
Юра
постоялец
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Юра »

Юнит lineinfo может вытаскивать по адресу инфу о месте в сорцах. Но для этого в экзешке должна быть отладочная информация.

Если такое не устраивает, то нужно самому писать парсер отладочной информации и на ее основе строить что-то свое. Затем стрипать экзешку от стандартной инфы...
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Юнит lineinfo может вытаскивать по адресу инфу о месте в сорцах.

Юнит lineinfo нихрена не пашет, ищет эту информацию не в том формате, в котором современный компилятор её добавляет в екзешник.
Да вы на дату этого юнита смотрели? 2000 год!
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Мы также видим, что рядом c lineinfo лежит lnfodwrf.pp...
Юра
постоялец
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Юра »

Cheb писал(а):Юнит lineinfo нихрена не пашет, ищет эту информацию не в том формате, в котором современный компилятор её добавляет в екзешник.
Да вы на дату этого юнита смотрели? 2000 год!


По умолчанию fpc генерит дебаг инфу в формате stabs (ключик -g) и ее понимает юнит lineinfo.
Ключик -gw генерит дебаг инфу в более современном формате dwarf. Для него, как было сказано, есть юнит lnfodwrf.pp

Насколько я знаю, виндовый gdb до сих пор не понимает dwarf. Поэтому "современность" это понятие относительное :)
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Мы также видим, что рядом c lineinfo лежит lnfodwrf.pp...

[звучно бьётся головой о ближайший твёрдый предмет] :oops:

...Значит, самодебажащаяся dll возможна таки? :D Обязательно проверю.
Это ж вековая мечта угнетённых - сразу знать, в какой строке навернулся эксцепшен.
Аватара пользователя
Attid
долгожитель
Сообщения: 2588
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

Значит, самодебажащаяся dll возможна таки?

не знаю что это такое, но чувствую что хАчу =)
если все заработает накидай примерчик плиз.
Alexey_Melky
новенький
Сообщения: 21
Зарегистрирован: 14.05.2005 14:55:31

Сообщение Alexey_Melky »

Большое спасибо всем, кто ответил. На данный момент видится следующее решение: компилировать проект с отладочной информацией, находить ее, например как это делает модуль lineinfo, записывать в отдельный файл, а затем прогонять загручный модуль через утилиту strip. Затем, если в процессе работы возникает исключение, загрузить отладочную инфу из отдельного файла и использовать тот же lineinfo.
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Припахал lnfodwrf, модифицировав её так, чтобы можно было указывать имя dll вручную. Вроде, запустилось... И дало на выходе кашу.
Включённая отладка показала, что оно нормально парсит один блок отладочной информации (относящийся к основному dpr библиотеки), а при переходе к следующему - неправильно вычисляет его смещение и идёт вразнос.
Надо разбираться, что там где не так, а у меня совершенно времени нет.
Юра
постоялец
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Юра »

lnfodwrf под Windows не доделан.
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Так я ж под Линуксом.
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Я уже близок к успеху.
Причина нерабочей linfodwrf - в небольших непредсказуемых сдвигах между модулями отладочной информации ( в районе одного-трёх байт). Я пока не смог выявить в них закономерность, поэтому моя модификация парсера использует хак, подбирая сдвиг методом перебора пока заголовок блока не станет похож на настоящий.

Увы, это *не* выравнивание на 32 или 64 бита - сдвиги действительно случайные.

Естественно, я строю свой модуль на совершенно других принципах (хотя код из linfodwrf выдираю вовсю). Один модуль умеет извлекать информацию о строках из екзешника, другой - парсить уже выдранную. ИМО, так гораздо гибче. Можно, например, выдрать эту инфу в отдельный файл, а остальную отладочную информацию (сотни килобайт) прибить strip'ом.
Мой модуль гораздо уже специализирован - жрёт только elf32.
Аватара пользователя
Cheb
энтузиаст
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34
Контактная информация:

Сообщение Cheb »

Поправка: не одного-трёх байт, а небольшого процента от длины блока. После большого блока и смещение большое [ворча, правит константу для хака]
Ответить