错误:longjmp导致未初始化的堆栈帧

时间:2012-02-08 10:37:51

标签: curl libcurl dbus

我有一个服务器应用程序,它在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 个答案:

答案 0 :(得分:36)

我遇到了同样的问题;如上所述,这是一个卷毛虫。我想我会在这里回答所有有关问题的可用信息。

来自the Red Hat bug report

  

没有异步解析器库的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可以调用异步处理程序unsafe函数(参见signal(7))   在这段时间内,它可以调用用户回调函数   绝对可以打电话。实际上,siglongjmp()本身并没有开启   POSIX的异步安全函数列表,这就是所有的libcurl   信号处理程序调用!

有几种方法可以解决此问题,具体取决于您是否构建了libcurl,或者您是否遇到了由您的发行版或系统管理员提供的问题:

  • 如果您无法重建libcurl,则可以在您使用的所有curl句柄上调用curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1)CURLOPT_NOSIGNAL笔记的文档:

      

    通过很久。如果是1,则libcurl将不使用任何函数   安装信号处理程序或任何导致信号发送的功能   到这个过程。这个选项主要是为了允许多线程   unix应用程序仍然设置/使用所有超时选项等,没有   冒险获取信号。 (在7.10中添加)

         

    如果设置了此选项并且已使用标准构建了libcurl   名称解析器,名称解析时不会发生超时   地方即可。考虑使用c-ares支持来构建libcurl以启用   异步DNS查找,可以为名称提供良好的超时   没有信号就解决了。

    在大多数情况下,显然需要DNS超时,因此这不是一个完美的解决方案。如果您能够在系统上重建libcurl,那么您可以......

  • 有一个名为c-ares的异步DNS解析程序库,curl能够用于名称解析。使用这个库是问题的首选解决方案(我想大多数Linux打包器现在已经解决了这个问题)。要启用c-ares支持,首先构建并安装库,然后在构建之前将--enable-ares标志传递给curl的configure脚本。 Full instructions are here

答案 1 :(得分:2)

这应该在curl 7.32.0中根据已经实现了线程DNS解析器的Debian changelog来修复。 Debian软件包处于不稳定状态,可以找到here

对于Ubuntu 12.04 - > 13.04你可以使用this PPA

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

Ubuntu 13.10包括curl 7.32所以不应该有这个问题。