2016-07-24 50 views
0

我使用C++ Rest SDK ("Casablanca")從Websocket服務器接收提要。目前,我使用websocket_callback_client class同時運行三個不同服務器的三個不同服務器。C++ Rest SDK卡薩布蘭卡Sigtrap

該程序運行一個未定義的時間,然後突然收到SIGTRAP, Trace/ Breakpoint trap。這是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 

在行#18的soruce /pplx/threadpool.h:133中給出。 這是圍繞這些線的源代碼:

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  } 

爲了清楚起見,m_serviceboost::asio::io_service。 對我來說,它看起來像#133行拋出一個異常,它被捕獲在#139行,然後rethrown。在這一點上,我必須親自抓住它,因爲如果我不這樣做,pplx -object會被未捕獲的異常破壞,它會提升SIGTRAP

這就是我的研究成果。問題是我沒有線索發生這種情況。我已經包圍了每個通過websocket_callback_client發送或從try {} catch(...){}收到數據的位置,並且它仍在發生。

也許有人曾經使用過這個庫可以幫助我。

+0

我得到了完全相同的錯誤,你最終設法解決這個問題嗎? –

+0

這是很久以前,但我認爲這是因爲我試圖通過一個封閉的套接字發送數據。 – Bobface

+0

這似乎是關於這個特定SDK的令人恐懼的事情之一。他們使用他們的線程池,但它並不容易出現異常,所以你最終得到了SIGTRAP。我發現在他們的任務中,如果你使用'.then()',那麼你的異常就不會被捕獲。您需要獲得任務,然後執行'.get()',然後銷燬任何形式的併發,因爲您現在被阻止在get上。 –

回答

1

根據我的經驗,這是由於一個單獨的問題。
當websocket_callback_client的關閉處理程序被調用時,大多數人試圖刪除websocket_callback_client。這在內部調用關閉功能。
發生這種情況時,websocket_callback_client將等待關閉完成。如果另一個線程意識到連接已經死亡並嘗試清理,則會從兩個不同的位置刪除相同的對象,這會導致重大問題。
Howto reconnect to a server which does not answer to close()對cpprestsdk調用關閉時發生的情況有相當全面的回顧。

希望這有助於:)

編輯: 事實證明(我在鏈接的問題給予迴應有這個),如果你嘗試從接近處理程序關閉或刪除websocket_callback_client它會調用自身關閉處理程序,它將鎖定線程。
我發現最適合我的解決方案是在關閉處理程序中設置一個標誌,並在主線程或至少一個備用線程中處理清理。

0

重溫這個。我找到了一個解決方法,我在cpprestsdk github上發佈了一個工作(https://github.com/Microsoft/cpprestsdk/issues/427)。

SDK在處理異常方面做得不好,在問題上我已經表明他們需要改進文檔以及提供一個乾淨的公共接口來做到這一點(您會看到解決方案有一個代碼聞到它)。

需要做的是重新拋出用戶異常。

這是在作出http_client請求調用的上下文中,但應適用於pplx的任何用法。

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 
     } 
    } 
}); 

的處理,以趕上「未觀察到的異常」在第二then()完成。

相關問題