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

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

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

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

Сообщение Alexey_Melky » 19.12.2007 17:27:38

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

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

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

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

Сообщение Brainenjii » 19.12.2007 18:12:22

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

Сообщение Alexey_Melky » 20.12.2007 11:45:00

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

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

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

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

Сообщение Юра » 20.12.2007 16:48:18

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

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

Сообщение Cheb » 21.12.2007 10:23:20

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

Юнит lineinfo нихрена не пашет, ищет эту информацию не в том формате, в котором современный компилятор её добавляет в екзешник.
Да вы на дату этого юнита смотрели? 2000 год!
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение Sergei I. Gorelkin » 21.12.2007 12:06:21

Мы также видим, что рядом c lineinfo лежит lnfodwrf.pp...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Юра » 21.12.2007 19:48:51

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


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

Насколько я знаю, виндовый gdb до сих пор не понимает dwarf. Поэтому "современность" это понятие относительное :)
Юра
постоялец
 
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Cheb » 27.12.2007 02:15:15

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

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

...Значит, самодебажащаяся dll возможна таки? :D Обязательно проверю.
Это ж вековая мечта угнетённых - сразу знать, в какой строке навернулся эксцепшен.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение Attid » 27.12.2007 13:58:11

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

не знаю что это такое, но чувствую что хАчу =)
если все заработает накидай примерчик плиз.
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2586
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Сообщение Alexey_Melky » 29.12.2007 12:43:48

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

Сообщение Cheb » 17.01.2008 18:18:15

Припахал lnfodwrf, модифицировав её так, чтобы можно было указывать имя dll вручную. Вроде, запустилось... И дало на выходе кашу.
Включённая отладка показала, что оно нормально парсит один блок отладочной информации (относящийся к основному dpr библиотеки), а при переходе к следующему - неправильно вычисляет его смещение и идёт вразнос.
Надо разбираться, что там где не так, а у меня совершенно времени нет.
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Сообщение Юра » 17.01.2008 20:11:08

lnfodwrf под Windows не доделан.
Юра
постоялец
 
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение Cheb » 17.01.2008 20:26:45

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

Сообщение Cheb » 28.01.2008 02:13:17

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

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

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

Сообщение Cheb » 28.01.2008 03:06:41

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

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 2

Рейтинг@Mail.ru
cron