curl - error: longjmp provoca un marco de pila no inicializado
libcurl dbus (2)
Esto se debe corregir en el curl 7.32.0 de acuerdo con el bugs.debian.org/cgi-bin/bugreport.cgi?bug=570436#74 Debian donde se implementó el resolutor DNS de subprocesos. El paquete Debian está en inestable y se puede encontrar here .
Para Ubuntu 12.04 -> 13.04 puede usar este PPA .
sudo apt-add-repository ppa:jaywink/curldebian
sudo apt-get update && sudo apt-get upgrade
Ubuntu 13.10 incluye curl 7.32, por lo que no debería tener este problema.
Tengo una aplicación de servidor que crea un Bus en el dbus y después de unos minutos de ejecución recibí un error que nunca había visto antes. ¿Tuviste una idea de lo que está mal?
*** 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]
Me encontré con el mismo problema; como se señaló anteriormente, es un error de rizo. Pensé que pondría una respuesta aquí para reunir toda la información disponible sobre el problema.
Del informe de errores de Red Hat :
libcurl creado sin una biblioteca de resolución asíncrona utiliza alarm () para detener las búsquedas de DNS. Cuando se produce un tiempo de espera, esto hace que libcurl salte desde el manejador de señales de vuelta a la biblioteca con un sigsetjmp, lo que efectivamente hace que libcurl continúe ejecutándose dentro del manejador de señal. Esto no es portátil y podría causar problemas en algunas plataformas. Una discusión sobre el problema está disponible en http://curl.haxx.se/mail/lib-2008-09/0197.html
Los "problemas en algunas plataformas" aparentemente se refieren a fallas en los sistemas Linux modernos al menos. Algunos detalles técnicos más profundos se encuentran en el enlace de la cita anterior:
Hay un problema con la forma en que libcurl maneja actualmente la señal SIGALRM. Instala un controlador para SIGALRM para obligar a una resolución DNS síncrona a un tiempo de espera después de un tiempo especificado, que es la única manera de abortar dicha resolución en algunos casos. Justo antes de que tenga lugar la resolución del DNS inicializa un puntero longjmp, de modo que cuando llega la señal, el manejador de señal simplemente hace un siglongjmp, el control continúa desde esa ubicación guardada y la función devuelve un código de error.
El problema es que todo el siguiente flujo de control se ejecuta de manera efectiva dentro del controlador de señal. No solo existe el riesgo de que libcurl pueda llamar a una función insegura del manejador asíncrono (vea la señal (7)) durante este tiempo, sino que podría llamar a una función de devolución de llamada del usuario que podría llamar absolutamente a cualquier cosa. De hecho, siglongjmp () en sí mismo no está en la lista POSIX de funciones async-safe, ¡y eso es todo lo que llama el controlador de señal libcurl!
Hay un par de formas de resolver este problema, dependiendo de si compiló libcurl o si está atascado con uno proporcionado por su distribución o administrador del sistema:
Si no puede reconstruir libcurl, puede llamar a
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1)
en todos los manejadores curl que use. La documentación para notasCURLOPT_NOSIGNAL
:Pasar por. Si es 1, libcurl no usará ninguna función que instale manejadores de señal o cualquier función que haga que se envíen señales al proceso. Esta opción está principalmente aquí para permitir que las aplicaciones Unix de múltiples subprocesos aún configuren / usen todas las opciones de tiempo de espera, etc., sin arriesgarse a recibir señales. (Agregado en 7.10)
Si esta opción está configurada y libcurl se ha creado con la resolución de nombres estándar, los tiempos de espera no se producirán mientras se produce la resolución del nombre . Considere la posibilidad de compilar libcurl con soporte c-are para habilitar búsquedas DNS asíncronas, lo que permite agradables tiempos de espera para resúmenes de nombres sin señales.
Los tiempos de espera de DNS son obviamente deseables en la mayoría de los casos, por lo que esta no es la solución perfecta. Si tiene la capacidad de reconstruir libcurl en su sistema, entonces puede ...
Hay una biblioteca de resolución de DNS asincrónica llamada c-ares que curl es capaz de usar para la resolución de nombres. Usar esta biblioteca es la solución preferida para el problema (y me imagino que la mayoría de los empaquetadores de Linux ya lo han descubierto). Para habilitar la compatibilidad con c-ares, primero compile e instale la biblioteca, luego pase la bandera
--enable-ares
al script deconfigure
de curl antes de compilar. Las instrucciones completas están aquí .