error: longjmp causes uninitialized stack frame

2019-01-31 13:12发布

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]

2条回答
干净又极端
2楼-- · 2019-01-31 13:27

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.

From 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

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:

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!

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:

  • 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:

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

  • 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.

查看更多
ら.Afraid
3楼-- · 2019-01-31 13:47

This should be fixed in curl 7.32.0 according to the Debian changelog where threaded DNS resolver has been implemented. The Debian package is in unstable and can be found here.

For Ubuntu 12.04 -> 13.04 you can use this PPA.

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

Ubuntu 13.10 includes curl 7.32 so should not have this problem.

查看更多
登录 后发表回答