2012-02-08 156 views
21

我有一个服务器应用程序,在dbus上创建一个总线,并在运行几分钟后出现一个我从未见过的错误。你有什么想法吗?错误:longjmp导致未初始化的堆栈帧

*** 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

[This thread](http://permalink.gmane.org/gmane.comp.systems.archos.rockbox.cvs/32841)表明这意味着你试图跳到已经退出的堆栈帧。 – 2012-02-08 11:11:52

+11

我解决了错误...它似乎是一个libcurl错误,并通过设置curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1)错误不再发生 – 2012-02-08 16:20:11

+2

把你的答案放入答案并接受它。我遇到了同样的问题,并用您编写的解决方案解决了这个问题。也许别人会发现这个问题以及谷歌搜索.. – getekha 2012-03-28 15:12:42

回答

31

我遇到了同样的问题;如上所述,这是一个卷曲错误。我想我会在这里提出一个答案,将所有关于问题的可用信息汇总在一起。

the Red Hat bug report

libcurl built without an asynchronous resolver library uses alarm() to time out DNS lookups. When a timeout occurs, this causes libcurl to jump from the signal handler back into the library with a sigsetjmp, which effectively causes libcurl to continue running within the signal handler. This is non-portable and could cause problems on some platforms. A discussion on the problem is available at http://curl.haxx.se/mail/lib-2008-09/0197.html

的“在某些平台上的问题”显然是指在现代的Linux系统崩溃,至少。一些更深层次的技术细节是从上面报价的链接:

There's a problem with the way libcurl currently handles the SIGALRM signal. It installs a handler for SIGALRM to force a synchronous DNS resolve to time out after a specified time, which is the only way to abort such a resolve in some cases. Just before the the DNS resolve takes place it initializes a longjmp pointer so when the signal comes in the signal handler just does a siglongjmp, control continues from that saved location and the function returns an error code.

The problem is that all the following control flow executes effectively inside the signal handler. Not only is there a risk that libcurl could call an async handler unsafe function (see signal(7)) during this time, but it could call a user callback function that could call absolutely anything. In fact, siglongjmp() itself is not on the POSIX list of async-safe functions, and that's all the libcurl signal handler calls!

有几种方法可以解决这个问题,这取决于你是否内置的libcurl或者如果你坚持一个由你的发行版提供或系统管理员:

  • 如果不能重建libcurl的,那么你可以调用curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1)所有卷曲处理您使用。为CURLOPT_NOSIGNAL注释的文档:

    Pass a long. If it is 1, libcurl will not use any functions that install signal handlers or any functions that cause signals to be sent to the process. This option is mainly here to allow multi-threaded unix applications to still set/use all timeout options etc, without risking getting signals. (Added in 7.10)

    If this option is set and libcurl has been built with the standard name resolver, timeouts will not occur while the name resolve takes place. Consider building libcurl with c-ares support to enable asynchronous DNS lookups, which enables nice timeouts for name resolves without signals.

    DNS超时显然期望在大多数情况下,所以这不是一个完美的修复。如果您有能力在您的系统上重建libcurl,那么您可以...

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

+1

这对我有用 – feisky 2012-07-09 07:42:50

+0

在这里工作多谢 – locojay 2013-02-20 04:25:18

+0

是否有可能从终端重现此错误?我的进程崩溃提供了类似的堆栈跟踪,但我无法验证问题是否相同。 – asloob 2015-08-04 01:17:36

2

这应根据Debian的changelog其中螺纹DNS解析器已经实现固定在卷曲7.32.0。 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所以不应该有这个问题。

+0

我已经更新了curl,所以当我调用'curl --version'时,我发现它的版本是7.32.0,但我仍然有同样的问题。在13.04,尽管一切正常。 – 2013-12-15 15:05:49

+0

对不起,哪个版本的Ubuntu发生问题,13.10? – jaywink 2013-12-17 09:31:57

+0

如果我正确阅读launchpad,在我看来,线程化的DNS解析器可能永远不会以7.32的启动板版本结束,它会做出更多检查 – jaywink 2013-12-17 09:40:22