我有一个服务器应用程序,它在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]
答案 0 :(得分:36)
我遇到了同样的问题;如上所述,这是一个卷毛虫。我想我会在这里回答所有有关问题的可用信息。
没有异步解析器库的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)