ошибка: longjmp вызывает неинициализированный кадр стека

У меня есть серверное приложение, которое создает шину на dbus, и через несколько минут работы я получил ошибку, которую никогда раньше не видел. У вас есть идея, что не так?

*** longjmp causes uninitialized stack frame ***: /home/user/Workspace/DBus_Server/Debug/DBus_Server terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7f8d8911c7f7]
/lib/x86_64-linux-gnu/libc.so.6(+0xf8789)[0x7f8d8911c789]
/lib/x86_64-linux-gnu/libc.so.6(__longjmp_chk+0x33)[0x7f8d8911c6f3]
/usr/lib/x86_64-linux-gnu/libcurl-nss.so.4(+0xd795)[0x7f8d88272795]
/lib/x86_64-linux-gnu/libc.so.6(+0x36420)[0x7f8d8905a420]
/lib/x86_64-linux-gnu/libc.so.6(__poll+0x53)[0x7f8d890f9773]
/usr/lib/libdbus-c++-1.so.0(_ZN4DBus15DefaultMainLoop8dispatchEv+0x161)[0x7f8d89b6b481]
/usr/lib/libdbus-c++-1.so.0(_ZN4DBus13BusDispatcher5enterEv+0x63)[0x7f8d89b6c293]
/home/user/Workspace/DBus_Server/Debug/DBus_Server[0x401333]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f8d8904530d]
/home/user/Workspace/DBus_Server/Debug/DBus_Server[0x4011c9]
22
задан Jason R 13 December 2012 в 16:00
поделиться

1 ответ

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

Из отчета об ошибках Red Hat :

libcurl, собранный без библиотеки асинхронного распознавателя, использует alarm () для тайм-аута поиска DNS. Когда происходит тайм-аут, это заставляет libcurl перейти из обработчика сигнала обратно в библиотеку с помощью sigsetjmp, что фактически заставляет libcurl продолжать работу в обработчике сигнала. Это непереносимо и может вызвать проблемы на некоторых платформах. Обсуждение этой проблемы доступно на http://curl.haxx.se/mail/lib-2008-09/0197.html

«Проблемы на некоторых платформах». "очевидно относится к сбоям в современных системах Linux по крайней мере. Некоторые более глубокие технические подробности приведены по ссылке из цитаты выше:

Существует проблема с тем, как libcurl в настоящее время обрабатывает сигнал SIGALRM. Он устанавливает обработчик для SIGALRM, чтобы принудительно разрешить синхронное разрешение DNS по истечении заданного времени, что является единственным способом прервать такое разрешение в некоторых случаях. Непосредственно перед разрешением DNS он инициализирует указатель longjmp, поэтому, когда сигнал поступает в обработчик сигнала, просто выполняет siglongjmp, управление продолжается из этого сохраненного местоположения, и функция возвращает код ошибки.

Проблема заключается в том, что весь следующий поток управления эффективно выполняется внутри обработчика сигнала. Существует не только риск того, что libcurl может вызвать небезопасную функцию асинхронного обработчика (см. Signal (7)) в течение этого времени, но также может вызвать функцию обратного вызова пользователя, которая может вызывать абсолютно все. На самом деле, siglongjmp () сам по себе отсутствует в списке асинхронно-безопасных функций POSIX, и это все вызовы обработчика сигналов libcurl!

Существует несколько способов решения этой проблемы, в зависимости от того, вы создали libcurl или если вы застряли с тем, который был предоставлен вашим дистрибутивом или системным администратором:

  • Если вы не можете перестроить libcurl, то вы можете вызвать curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1) для всех скручиваемость ручки, которые вы используете. Документация для CURLOPT_NOSIGNAL отмечает:

    Пройдите длинный. Если это значение равно 1, libcurl не будет использовать какие-либо функции, которые устанавливают обработчики сигналов, или любые функции, которые вызывают отправку сигналов процессу. Эта опция в основном здесь, чтобы позволить многопоточным приложениям Unix по-прежнему устанавливать / использовать все параметры тайм-аута и т. Д., Не рискуя получить сигналы. (Добавлено в 7.10)

    Если эта опция установлена ​​и libcurl был собран со стандартным преобразователем имен, тайм-ауты не произойдут, пока происходит разрешение имени . Подумайте о создании libcurl с поддержкой c-ares для включения асинхронного поиска DNS, который обеспечивает хорошие тайм-ауты для разрешения имен без сигналов.

    Тайм-ауты DNS, очевидно, желательно иметь в большинстве случаев, так что это не идеальное решение. Если у вас есть возможность пересобрать libcurl в вашей системе, то вы можете ...

  • Существует библиотека асинхронного распознавателя DNS под названием c-ares , которую curl может использовать для разрешения имен. Использование этой библиотеки является предпочтительным решением проблемы (и я полагаю, что большинство сборщиков Linux уже поняли это). Чтобы включить поддержку c-ares, сначала соберите и установите библиотеку, затем перед сборкой передайте флаг --enable-ares сценарию curl configure. Полные инструкции здесь .

36
ответ дан 29 November 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: