2013-09-19 13 views
6

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

Если мое приложение падает с Segfault, из-за ошибки в основной исполняемый двоичный файл, я могу анализировать трассировку с:

addr2line -Cif -e ./myapplication 0x4... 

Это точно отображает функцию и source_file: LINE_NO

Однако как анализировать, произошел ли сбои из-за ошибки в плагине, как в обратном направлении ниже?

/opt/myapplication(_Z7sigsegvv+0x15)[0x504245] 
/lib64/libpthread.so.0[0x3f1c40f500] 
/opt/myapplication/modules/myplugin.so(_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi+0x6af)[0x7f5588fe4bbf] 
/opt/myapplication/modules/myplugin.so(_Z11myplugin_reqmodP12CONNECTION_TP7Filebuf+0x68)[0x7f5588fe51e8] 
/opt/myapplication(_ZN10Processors7ExecuteEiP12CONNECTION_TP7Filebuf+0x5b)[0x4e584b] 
/opt/myapplication(_Z15process_requestP12CONNECTION_TP7Filebuf+0x462)[0x4efa92] 
/opt/myapplication(_Z14handle_requestP12CONNECTION_T+0x1c6d)[0x4d4ded] 
/opt/myapplication(_Z13process_entryP12CONNECTION_T+0x240)[0x4d79c0] 
/lib64/libpthread.so.0[0x3f1c407851] 
/lib64/libc.so.6(clone+0x6d)[0x3f1bce890d] 

Как мои приложения, так и библиотеки плагинов были скомпилированы с помощью gcc и не установлены. Мое приложение при выполнении, загружает plugin.so с помощью dlopen К сожалению, авария происходит на сайте, где я не могу запустить приложение под gdb.

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

Тонкости благодарности заранее.

+0

Есть ли что-то особенное в этих «библиотеках плагинов» или это просто стандартные общие библиотеки? – us2012

+0

Кроме того, вы видели этот вопрос SO http://stackoverflow.com/questions/7556045/how-to-map-function-address-to-function-in-so-files? – us2012

+0

@ us2012 Да, я проверил эту ссылку несколько месяцев назад, а также попросил немного более ясности в деривации, см. Мой комментарий. Btw. мои библиотеки плагинов - это простые c/C++, поэтому объекты, ничего особенного в них. Искреннее спасибо за интерес. – mdk

ответ

5

Вот несколько советов, которые могут помочь вам отладить это:

Адреса в вашей трассировке это адрес в адресном пространстве процесса в момент его разбитым. Это означает, что если вы хотите перевести его в «физический» адрес относительно начала раздела .text вашей библиотеки, вы должны вычесть начальный адрес соответствующего раздела pmap с адреса в вашем обратном направлении.

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

В вашем положении, я хотел бы попробовать:

  • декодировании имена символов с c++filt -n или вручную. Сейчас у меня нет оболочки, поэтому вот моя ручная попытка: _ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi - ICAPSection::process(CONNECTION_T *, Filebuf *, int). Это может быть полезно. Если нет:
  • objdump или nm (я уверен, что они могут это сделать), чтобы найти адрес, соответствующий искаженному имени, затем добавьте смещение (+0x6af в соответствии с вашим стеклом), затем найдите результат адрес с addr2line.
+1

Бинго! Вы абсолютно прибивали его. Это сработало и точно. Не могу вас поблагодарить. Я знал, что у меня здесь будет туз. Еще раз спасибо. – mdk

+0

@mdk Рад помочь. Какой вариант работал для вас? 'Objdump'? – us2012

+0

Я использовал nm. В нем меньше коммутаторов, а выход более прост в использовании. Посмотрите ниже, я разработал ваш совет, надеюсь, правильно. Приветствия. – mdk

4

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

В обратном направлении ясно видно, что недостаток существует в коде myplugin.so.И трассировку указывает на то, что она существует в:

/opt/myapplication/modules/myplugin.so(_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi+0x6af)[0x7f5588fe4bbf] 

Задача размещения линии, соответствующей этой неисправности не может быть определена как упрощенно, как:

addr2line -Cif -e /opt/myapplication/modules/myplugin.so 0x7f5588fe4bbf 

Правильным здесь было бы использовать нм или objdump, чтобы определить адрес, указывающий на искаженное имя. (Замена, как это сделано нами2012, на самом деле на самом деле не нужна). Таким образом, используя:

nm -Dlan /opt/myapplication/modules/myplugin.so | grep "_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi" 

я получаю:

0000000000008510 T _ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi /usr/local/src/unstable/myapplication/sources/modules/myplugin/myplugin.cpp:518 

Интересно отметить, что myplugin.cpp: 518 фактически указывает на строку, где открытие "{" функции ICAPSection :: процесс (CONNECTION_T *, Filebuf *, Int)

Далее мы добавим 0x6af по адресу (выявленной выход нм выше) 0000000000008510 с помощью команды оболочки Linux

printf '0x%x\n' $((0x0000000000008510 + 0x6af)) 

И что приводит к 0x8bbf

И это фактическое source_file: LINE_NO неисправного кода, и может быть точно определено с addr2line как:

addr2line -Cif -e /opt/myapplication/modules/myplugin.so 0x8bbf 

который отображает:

std::char_traits<char>::length(char const*) 
/usr/include/c++/4.4/bits/char_traits.h:263 
std::string::assign(char const*) 
/usr/include/c++/4.4/bits/basic_string.h:970 
std::string::operator=(char const*) 
/usr/include/c++/4.4/bits/basic_string.h:514 
?? 
/usr/local/src/unstable/myapplication/sources/modules/myplugin/myplugin.cpp:622 

Я не слишком уверен, почему имя функции здесь не отображается, но myplugin.cpp: 622 было совершенно точно где была ошибка.