错误:longjmp导致未初始化的堆栈帧 [英] error: longjmp causes uninitialized stack frame

查看:1553
本文介绍了错误:longjmp导致未初始化的堆栈帧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个服务器应用程序,在dbus上创建一个总线,几分钟后运行我得到一个错误,我从来没有见过。

I have a server application that creates a Bus on the dbus and after some minutes of running I got an error that I have never seen before. Did you have an idea whats wrong?

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


推荐答案

如上所述,它是一个curl bug。我想我会在这里提供一个答案,将所有可用的问题信息集中在一起。

I ran into the same issue; as noted above, it is a curl bug. I thought I would put an answer up here to pull together all of the available information on the problem.

红帽错误报告


libcurl没有异步解析器库使用alarm()到
超时DNS查找。当超时发生时,这会导致libcurl
从信号处理程序跳转到库中,并带有一个sigsetjmp
,它有效地导致libcurl继续在
信号处理程序中运行。这是非便携式的,可能会导致一些
平台的问题。有关此问题的讨论可在
http:// curl .haxx.se / mail / lib-2008-09 / 0197.html

某些平台上的问题显然是指至少在现代Linux系统上的崩溃。一些更深入的技术细节在上面的链接:

The "problems on some platforms" apparently refers to crashes on modern Linux systems at least. Some deeper technical details are at the link from the quote above:


libcurl当前处理SIGALRM的方式有一个问题
信号。它安装一个SIGALRM的处理程序强制同步DNS
解决在指定的时间后超时,这是在某些情况下中止这种解决的唯一途径。在DNS解析
之前,它初始化一个longjmp指针,所以当信号处理程序中的信号来自
只是一个siglongjmp时,控制从
继续保存位置,函数返回一个错误代码。

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.

问题是所有以下控制流在信号处理程序中有效地执行
。不仅有一个风险
libcurl可以调用异步处理程序不安全的函数(见信号(7))
在这段时间,但它可以调用一个用户回调函数
可以调用绝对任何东西。事实上,siglongjmp()本身不是在
的POSIX列表的异步安全函数,这是所有libcurl
信号处理程序调用!

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,或者如果你遇到了由你的发行版或系统管理员提供的:

There are a couple ways to solve this problem, depending upon whether you built libcurl or if you're stuck with one that was provided by your distribution or system admin:


  • 如果无法重建libcurl,那么可以调用 curl_easy_setopt(curl,CURLOPT_NOSIGNAL,1)在您使用的所有curl句柄。 CURLOPT_NOSIGNAL 注释的文档:

  • If you can't rebuild libcurl, then you can call curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1) on all curl handles that you use. The documentation for CURLOPT_NOSIGNAL notes:


通过一个长。如果它是1,libcurl不会使用任何函数
安装信号处理程序或任何函数,导致信号发送
到过程。这个选项主要是允许多线程
unix应用程序仍然设置/使用所有超时选项等,而没有
的风险获得信号。 (在7.10中添加)

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)

如果设置了此选项并且libcurl已使用标准
名称解析器构建,则名称解决需要
地方
。考虑使用c-ares支持来构建libcurl,以启用
异步DNS查找,这使得名称
的优秀超时可以无信号地解析。

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,那么您可以...

DNS timeouts are obviously desirable to have in most cases, so this isn't a perfect fix. If you have the ability to rebuild libcurl on your system, then you can...

有一个异步DNS解析器库称为 c-ares curl能够用于名称解析。使用这个库是解决这个问题的首选方法(我想大多数Linux软件包都已经知道了这一点)。要启用c-ares支持,首先构建并安装库,然后将 - enable-ares 标志传递给curl的 configure 脚本。 完整说明在这里

There is an asynchronous DNS resolver library called c-ares that curl is capable of using for name resolution. Using this library is the preferred solution to the problem (and I would imagine most Linux packagers have figured this out by now). To enable c-ares support, first build and install the library, then pass the --enable-ares flag to curl's configure script before you build. Full instructions are here.

这篇关于错误:longjmp导致未初始化的堆栈帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆