В моем приложении я установил обработчик сигнала, чтобы перехватить ошибки сегмента и распечатать бактры.
Мое приложение загружает некоторые библиотеки плагинов, когда начинается процесс.
Если мое приложение завершается сбоем из-за ошибки из-за ошибки в основном исполняемом двоичном файле, я могу проанализировать обратную трассировку с помощью:
addr2line -Cif -e ./myapplication 0x4...
Он точно отображает функцию и исходный_файл: 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, исключают сценарии, в которых может потребоваться анализ неисправных плагинов.
Я надеюсь, что какой-нибудь добросердечный хак знает решение этой дилеммы и может поделиться некоторыми идеями. Это было бы так неоценимо для коллег-программистов.
Тонны спасибо заранее.
Вот несколько советов, которые могут помочь вам отладить это:
Адрес в вашей трассировке является адресом в адресном пространстве процесса в момент его сбоя. Это означает, что если вы хотите перевести его в «физический» адрес относительно начала .text
раздел вашей библиотеки, вы должны вычесть начальный адрес соответствующего раздела pmap
с адреса в вашем следе.
К сожалению, это означает, что вам нужен pmap
процесса, прежде чем он потерпел крах. По общему признанию, я понятия не имею, является ли загрузка адресов для библиотек в одной системе постоянной, если вы закроете и повторно запустите ее (возможно, есть функции безопасности, которые рандомизируют это), но, как вы заметили, она, безусловно, не переносима между системами.
На вашей позиции я бы попробовал:
c++filt -n
или вручную. У меня сейчас нет оболочки, поэтому вот моя попытка вручную: _ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi
является ICAPSection::process(CONNECTION_T *, Filebuf *, int)
, Это уже может быть полезно. Если не: objdump
или же nm
(Я почти уверен, что они могут это сделать), чтобы найти адрес, соответствующий искаженному имени, а затем добавить смещение (+0x6af
согласно вашей стековой трассировке) к этому, затем ищите результирующий адрес с addr2line
,Ответ us2012 был довольно хитрым, чтобы решить проблему. Я просто пытаюсь повторить это здесь, просто чтобы помочь любому другому новичку, борющемуся с той же самой проблемой, или если кто-то хочет предложить улучшения.
В обратном следе ясно видно, что в коде для myplugin.so существует недостаток. И обратный след указывает, что он существует в:
/opt/myapplication/modules/myplugin.so(_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi+0x6af)[0x7f5588fe4bbf]
Проблема определения местоположения линии, соответствующей этой ошибке, не может быть определена так просто:
addr2line -Cif -e /opt/myapplication/modules/myplugin.so 0x7f5588fe4bbf
Правильной процедурой здесь будет использование nm или 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 :: process (CONNECTION_T *, Filebuf *, int)
Затем мы добавляем 0x6af к адресу (показан выводом nm выше) 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 было совершенно точно, где вина.