2016-07-24 2 views
0

C++ Rest SDK ("Casablanca")을 사용하여 Websocket-Servers에서 피드를 수신합니다. 현재는 websocket_callback_client class을 사용하여 동시에 실행되는 세 개의 다른 서버에 세 가지 다른 연결이 있습니다.C++ Rest SDK Casablanca Sigtrap

프로그램이 정의되지 않은 시간 동안 실행되고 갑자기 SIGTRAP, Trace/ Breakpoint trap을 수신합니다.

#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 /pplx/threadpool.h:133가 주어진다 soruce에서 :이 GDB의 출력이다. 대한 명확한

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 번 줄에 붙잡힌 다음 다시 던지게된다. 이 시점에서 개인적으로 잡으려고합니다. 그렇지 않은 경우 pplx -object가 캐치되지 않은 예외로 파괴되면 SIGTRAP이 발생합니다.

이것은 내가 연구 한 결과입니다. 문제는 이것이 일어나고있는 단서가 없다는 것입니다. 나는 데이터가 전송되거나 websocket_callback_client에서 수신 된 모든 위치를 try {} catch(...){}으로 묶었지만 여전히 발생합니다.

아마도이 라이브러리를 사용했던 사람이 나를 도울 수 있습니다.

+0

정확한 오류가 발생했습니다. 결국이 문제를 해결할 수 있었습니까? –

+0

꽤 오래 전 이었지만 닫힌 소켓을 통해 데이터를 보내려고했기 때문에 생각했습니다. – Bobface

+0

이것은이 특정 SDK에 대해 끔찍한 일 중 하나처럼 보입니다. 스레드 풀을 사용하지만 예외가 쉽게 발생하지 않으므로 SIGTRAP으로 끝납니다. 나는 그들의 작업으로'.then()'을 사용하면 예외가 잡히지 않는 것을 발견했다. 당신은 작업을 얻고 나서'.get()'을 할 필요가있다. 그러면 당신은 이제 get에 막혀 있기 때문에 동시성의 어떤 형태를 파괴한다. –

답변

1

제 경험상이 문제는 별도의 문제로 인해 발생합니다.
websocket_callback_client의 닫기 처리기가 호출되면 대부분의 사람들은 websocket_callback_client를 삭제하려고합니다. 이것은 내부적으로 close 함수를 호출합니다.
이 경우 websocket_callback_client가 닫기를 완료 할 때까지 기다립니다. 다른 스레드가 연결이 끊어 졌음을 인식하고 정리하려고 시도하면 동일한 위치에 두 개의 다른 위치에서 동일한 개체가 삭제되어 심각한 문제가 발생할 수 있습니다.
Howto reconnect to a server which does not answer to close()에는 cpprestsdk이 (가) 가까이에 전화 할 때 어떤 일이 발생하는지에 대한 철저한 검토가 있습니다.

희망이 도움이 :)

편집 : 그것 (I 링크 된 질문에 준 응답이있다) 나오는 것에 따라 당신이 가까운 핸들러에서 닫거나 websocket_callback_client을 삭제하려고하면 은, 그 자체가 호출 thread를 잠그는 클로우즈 핸들러
내가 가장 잘 작동하는 것으로 밝혀진 해결책은 닫기 처리기에 플래그를 설정하고 주 스레드 또는 적어도 대체 스레드에서 정리를 처리하는 것입니다.

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()에서 수행되는 것을 잡으려고.

관련 문제