2012-05-04 2 views
3

Я пытаюсь получить и сохранить трассировку стека в файл после получения SEGSEGV внутри моей общей библиотеки. Общая библиотека является плагином для продукта с закрытым исходным кодом. Все это работает на производстве, и у меня нет прямого доступа к нему.Функция backtrace внутри разделяемых библиотек

Мой код улавливает SIGSEGV сигнал, печатает трассировку стека и выходы. У меня есть что-то вроде этого:

/opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019f11] /opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc2019f11] /опт/ecelerity/libexec /site/ec_attachextensions.so [0x2aecc2019fee] /opt/ecelerity/libexec/site/ec_attachextensions.so [0x2aecc201a587]

/Opt/ecelerity/SBIN/ecelerity [0x5]

/Opt/ecelerity/SBIN/ecelerity (sieve_seng_execute + 0x82) [0x506d32] /opt/ecelerity/libexec/validate/sieve.so [ 0x2aecc2862c9e] /Opt/ecelerity/SBIN/ecelerity (validate_data + 0xA5) [0x4a90d5] /Opt/ecelerity/SBIN/ecelerity (esmtp_message_factory + 0x154e) [0x46eace] /Opt/ecelerity/SBIN/ecelerity (schedule_event_and_dispatch + 0x6a) [0x49c59a]

проблема заключается в том, что я не могу иметь имена функций и смещений внутри них для общего библиотеки. Насколько я понимаю, я могу найти имя функции/имя файла для данного адреса с помощью утилиты addr2line после того, как найду библиотеку смещения в /proc/$PID/maps.

После того, что я что-то подобное исполнение:

addr2line -e /opt/ecelerity/libexec/site/ec_attachextensions.so (LIBRARY_OFFSET_FROM_MAPS_FILE - 0x2aecc2019f11) 

Где 0x2aecc2019f11 это адрес от трассировки стека выше. Мне было интересно, есть ли способ получить имена функций в трассировке стека, не касаясь файлов карт? Другими словами, как я могу запрограммировать его? Был бы dladdr help здесь (dladdr не смог получить имена функций с адресов, предоставленных backtrace функцией в моем случае)?

ответ

1

код backtrace использует примерно тот же механизм, что и dladdr, для определения имен функций.

Если ваша библиотека построена с использованием файла карты компоновщика (который определяет, что экспортируется, и может использоваться для ограничения видимости всех других элементов) или -fvisibility=hidden с явными видимыми символами, тогда он скрывает символы так что они не появятся на выходе backtrace.

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

Чтобы заставить его работать без этого, вам нужно загрузить локальную таблицу символов из .so и определить расположения символов, используя механизм, подобный addr2line. Механизм для этого состоит в том, чтобы использовать libelf1. для чтения таблицы локальных символов.

... Это, конечно, требует, чтобы таблица не была удалена из файла. Если это так, то ни один из этих трюков не имеет значения как .so просто не приходит с информацией.

1

Вы можете иметь обработчик сигнала чтения/proc/self/maps для вас.

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

Но я не удивлюсь, если есть функция динамического компоновщика, которая даст вам базовый адрес - вы можете проверить документы для этого.

Смежные вопросы