2016-07-24 11 views
0

Ich verwende die , um Feed von Websocket-Servern zu erhalten. Zurzeit habe ich drei verschiedene Verbindungen zu drei verschiedenen Servern, die gleichzeitig mit der websocket_callback_client class ausgeführt werden.C++ Rest SDK Casablanca Sigtrap

Das Programm läuft für eine unbestimmte Zeit und empfängt dann plötzlich . Dies ist die Ausgabe von GDB:

#0 0x00007ffff5abec37 in __GI_raise (sig=5) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 
#1 0x000000000047bb8e in pplx::details::_ExceptionHolder::~_ExceptionHolder()() 
#2 0x000000000044be29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release()() 
#3 0x000000000047fa39 in pplx::details::_Task_impl<unsigned char>::~_Task_impl()() 
#4 0x000000000044be29 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release()() 
#5 0x00007ffff6feb09f in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7fffc8021420, __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/shared_ptr_base.h:546 
#6 0x00007ffff6fffa38 in std::__shared_ptr<pplx::details::_Task_impl<unsigned char>, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x7fffc8021418, __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/shared_ptr_base.h:781 
#7 0x00007ffff6fffa52 in std::shared_ptr<pplx::details::_Task_impl<unsigned char> >::~shared_ptr (this=0x7fffc8021418, __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/shared_ptr.h:93 
#8 0x00007ffff710f766 in pplx::details::_PPLTaskHandle<unsigned char, pplx::task<unsigned char>::_InitialTaskHandle<void, void web::websockets::client::details::wspp_callback_client::shutdown_wspp_impl<websocketpp::config::asio_tls_client>(std::weak_ptr<void> const&, bool)::{lambda()#1}, pplx::details::_TypeSelectorNoAsync>, pplx::details::_TaskProcHandle>::~_PPLTaskHandle() (this=0x7fffc8021410, __in_chrg=<optimized out>) 
    at /home/cpprestsdk/Release/include/pplx/pplxtasks.h:1631 
#9 0x00007ffff716e6f2 in pplx::task<unsigned char>::_InitialTaskHandle<void, void web::websockets::client::details::wspp_callback_client::shutdown_wspp_impl<websocketpp::config::asio_tls_client>(std::weak_ptr<void> const&, bool)::{lambda()#1}, pplx::details::_TypeSelectorNoAsync>::~_InitialTaskHandle() (this=0x7fffc8021410, __in_chrg=<optimized out>) at /home/cpprestsdk/Release/include/pplx/pplxtasks.h:3710 
#10 0x00007ffff716e722 in pplx::task<unsigned char>::_InitialTaskHandle<void, void web::websockets::client::details::wspp_callback_client::shutdown_wspp_impl<websocketpp::config::asio_tls_client>(std::weak_ptr<void> const&, bool)::{lambda()#1}, pplx::details::_TypeSelectorNoAsync>::~_InitialTaskHandle() (this=0x7fffc8021410, __in_chrg=<optimized out>) at /home/cpprestsdk/Release/include/pplx/pplxtasks.h:3710 
#11 0x00007ffff71f9cdd in boost::_bi::list1<boost::_bi::value<void*> >::operator()<void (*)(void*), boost::_bi::list0> (this=0x7fffdc7d7d28, [email protected]: 0x479180 <pplx::details::_TaskProcHandle::_RunChoreBridge(void*)>, a=...) 
    at /usr/local/include/boost/bind/bind.hpp:259 
#12 0x00007ffff71f9c8f in boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > >::operator() (this=0x7fffdc7d7d20) at /usr/local/include/boost/bind/bind.hpp:1222 
#13 0x00007ffff71f9c54 in boost::asio::asio_handler_invoke<boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > > > (function=...) at /usr/local/include/boost/asio/handler_invoke_hook.hpp:69 
#14 0x00007ffff71f9bea in boost_asio_handler_invoke_helpers::invoke<boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > >, boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > > > (function=..., context=...) at /usr/local/include/boost/asio/detail/handler_invoke_helpers.hpp:37 
#15 0x00007ffff71f9b2e in boost::asio::detail::completion_handler<boost::_bi::bind_t<void, void (*)(void*), boost::_bi::list1<boost::_bi::value<void*> > > >::do_complete (owner=0x7488d0, base=0x7fffc801ecd0) 
    at /usr/local/include/boost/asio/detail/completion_handler.hpp:68 
#16 0x00000000004c34c1 in boost::asio::detail::task_io_service::run(boost::system::error_code&)() 
#17 0x00007ffff709fb27 in boost::asio::io_service::run (this=0x7ffff759ab78 <crossplat::threadpool::shared_instance()::s_shared+24>) at /usr/local/include/boost/asio/impl/io_service.ipp:59 
#18 0x00007ffff7185a81 in crossplat::threadpool::thread_start (arg=0x7ffff759ab60 <crossplat::threadpool::shared_instance()::s_shared>) at /home/cpprestsdk/Release/include/pplx/threadpool.h:133 
#19 0x00007ffff566e184 in start_thread (arg=0x7fffdc7d8700) at pthread_create.c:312 
#20 0x00007ffff5b8237d in clone() at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 

In Zeile # 18 die soruce /pplx/threadpool.h:133 gegeben. Dies ist die Quelle-Code um diese Zeilen:

123  static void* thread_start(void *arg) 
    124  { 
    125 #if (defined(ANDROID) || defined(__ANDROID__)) 
    126   // Calling get_jvm_env() here forces the thread to be attached. 
    127   get_jvm_env(); 
    128   pthread_cleanup_push(detach_from_java, nullptr); 
    129 #endif 
    130   threadpool* _this = reinterpret_cast<threadpool*>(arg); 
    131   try 
    132   { 
    133    _this->m_service.run(); 
    134   } 
    135   catch (const _cancel_thread&) 
    136   { 
    137    // thread was cancelled 
    138   } 
    139   catch (...) 
    140   { 
    141    // Something bad happened 
    142 #if (defined(ANDROID) || defined(__ANDROID__)) 
    143    // Reach into the depths of the 'droid! 
    144    // NOTE: Uses internals of the bionic library 
    145    // Written against android ndk r9d, 7/26/2014 
    146    __pthread_cleanup_pop(&__cleanup, true); 
    147    throw; 
    148 #endif 
    149   } 
    150 #if (defined(ANDROID) || defined(__ANDROID__)) 
    151   pthread_cleanup_pop(true); 
    152 #endif 
    153   return arg; 
    154  } 

Zur Verdeutlichung m_service ein boost::asio::io_service ist. Für mich sieht es so aus, dass Zeile # 133 eine Ausnahme auslöst, sie wird in Zeile 139 gefangen und dann wieder aufgetaut. An diesem Punkt muss ich es persönlich fangen, denn wenn ich das nicht mache und das pplx -Objekt mit einer nicht abgefangenen Ausnahme zerstört wird, wird es SIGTRAP auslösen.

Das ist, wie weit ich mit meinen Nachforschungen gekommen bin. Das Problem ist, ich habe keine Ahnung, wo das passiert. Ich habe jede Position umgeben, wo Daten gesendet oder empfangen werden von websocket_callback_client mit try {} catch(...){} und es ist immer noch passiert.

Vielleicht kann jemand, der diese Bibliothek zuvor benutzt hat, mir helfen.

+0

Ich bekomme den genau gleichen Fehler, hast du es geschafft, dies am Ende zu beheben? –

+0

Es war ziemlich lange her, aber ich denke, es war, weil ich versuchte, Daten durch eine geschlossene Steckdose zu senden. – Bobface

+0

Dies scheint eines der erschreckenden Dinge über dieses spezielle SDK zu sein. Sie verwenden ihren Thread-Pool, aber da sie keine Ausnahmen darstellen, haben Sie am Ende SIGTRAPs. Ich habe festgestellt, dass bei ihren Aufgaben, wenn Sie '.then()' verwenden, Ihre Ausnahmen nicht abgefangen werden. Sie müssen die Aufgabe abrufen und dann eine '.get()' ausführen, die dann jede Form von Nebenläufigkeit zerstört, da Sie jetzt auf dem Get blockiert sind. –

Antwort

1

Meiner Erfahrung nach geschieht dies aufgrund eines separaten Problems.
Wenn der close-Handler von websocket_callback_client aufgerufen wird, versuchen die meisten Leute, den websocket_callback_client zu löschen. Dies ruft intern die Schließfunktion auf.
Wenn dies geschieht, wartet der websocket_callback_client auf den Abschluss. Wenn ein anderer Thread erkennt, dass die Verbindung inaktiv ist und versucht, die Verbindung zu bereinigen, wird das gleiche Objekt an zwei verschiedenen Orten gelöscht, was zu schwerwiegenden Problemen führt.
Howto reconnect to a server which does not answer to close() hat eine ziemlich gründliche Überprüfung dessen, was passiert, wenn cpprestdk Anrufe in der Nähe.

this helps :)

Edit: Wie sich herausstellt (die Antwort, die ich in der verknüpften Frage gab hat dies), wenn Sie versuchen, die websocket_callback_client aus der Nähe Handler zu schließen oder löschen wird es selbst nennen der Close-Handler, der den Thread sperrt.
Die Lösung, die ich gefunden habe, die am besten für mich funktioniert, besteht darin, ein Flag im close-Handler zu setzen und die Bereinigung im Haupt-Thread oder zumindest einen alternativen Thread zu behandeln.

0

Dies nochmals aufrufen. Ich habe eine Arbeit gefunden, die ich auf dem cpprestdk github (https://github.com/Microsoft/cpprestsdk/issues/427) gepostet habe.

Das SDK hat eine schlechte Arbeit beim Auftauchen von Ausnahmen und in dem Problem habe ich angegeben, dass sie die Dokumentation zu verbessern haben und eine saubere öffentliche Schnittstelle zur Verfügung stellen müssen (Sie werden sehen, die Lösung hat einen Code rieche daran).

Was Sie tun müssen, ist die Benutzerausnahme erneut zu lösen.

Dies ist im Zusammenhang mit einer Anfrage http_client Anfrage, sollte aber für jede Verwendung von pplx anwendbar sein.

client->request(request).then([=] (web::http::http_response response) mutable { 
    // Your code here 
}).then([=] (pplx::task<void> previous_task) mutable { 
    if (previous_task._GetImpl()->_HasUserException()) { 
     auto holder = previous_task._GetImpl()->_GetExceptionHolder(); // Probably should put in try 

     try { 
      // Need to make sure you try/catch here, as _RethrowUserException can throw 
      holder->_RethrowUserException(); 
     } catch (std::exception& e) { 
      // Do what you need to do here 
     } 
    } 
}); 

Die Handhabung, daß „unbeobachtet Ausnahme“ fangen in den zweiten then() erfolgt.

Verwandte Themen