ошибка: longjmp вызывает неинициализированный кадр стека - PullRequest
22 голосов
/ 08 февраля 2012

У меня есть серверное приложение, которое создает шину на шине 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]

Ответы [ 2 ]

36 голосов
/ 25 мая 2012

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

С отчет об ошибке 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. Полные инструкции здесь .

2 голосов
/ 31 августа 2013

Это должно быть исправлено в curl 7.32.0 в соответствии с Debian changelog , где был реализован многопоточный преобразователь DNS.Пакет Debian находится в нестабильном состоянии и может быть найден здесь .

Для Ubuntu 12.04 -> 13.04 вы можете использовать этот PPA .

sudo apt-add-repository ppa:jaywink/curldebian
sudo apt-get update && sudo apt-get upgrade

Ubuntu 13.10 включает в себя curl 7.32, поэтому не должно быть этой проблемы.

...