C++基于Boost.Asio的多线程WebSocket客户端EXC_BAD_ACCESS问题排查
问题:Boost.Beast WebSocket握手偶发段错误(EXC_BAD_ACCESS)
我使用Boost.Beast和Boost.Asio开发C++多线程WebSocket客户端,用于处理服务器的实时数据流。偶尔会在WebSocket握手过程(do_handshake方法)中遇到段错误(EXC_BAD_ACCESS)。
WebSocketClient类简化版本:
class WebSocketClient { private: OrderBook &orderBook_; string coin_; boost::asio::io_context ioc_; tcp::resolver resolver_; ssl::context ssl_context_; websocket::stream<boost::asio::ssl::stream<tcp::socket>> ws_; public: WebSocketClient(OrderBook &orderBook, const string &coin) : orderBook_(orderBook), coin_(coin), resolver_(ioc_), ssl_context_(ssl::context::tlsv12_client), ws_(ioc_, ssl_context_) { ssl_context_.set_default_verify_paths(); ws_.next_layer().set_verify_mode(ssl::verify_peer); ws_.next_layer().set_verify_callback(ssl::rfc2818_verification("stream.binance.com")); } void connectAndSubscribe() { try { cout << "&ws_ = " << &ws_ << endl; // 解析主机名并连接服务器 auto const results = resolver_.resolve("stream.binance.com", "9443"); auto ep = boost::asio::connect(ws_.next_layer().next_layer(), results); string host_ = "stream.binance.com:" + to_string(ep.port()); ws_.next_layer().handshake(ssl::stream_base::client); // 设置装饰器修改握手的User-Agent ws_.set_option(websocket::stream_base::decorator( [](websocket::request_type &req) { req.set(boost::beast::http::field::user_agent, string(BOOST_BEAST_VERSION_STRING) + " websocket-client"); })); string path = "/ws/" + coin_ + "@depth5@100ms"; ws_.handshake(host_, path); cout << "Handshake successful." << endl; string msg = "{\"method\": \"SUBSCRIBE\", \"params\": [\"" + coin_ + "@depth5@100ms\"], \"id\": 1}"; send(msg); cout << "Subscription request done!" << endl; } catch (const std::exception &e) { cout << "Error in connectAndSubscribe: " << e.what() << endl; throw; // 重新抛出以便调用者捕获 } } };
该类在多线程环境中使用,每个线程创建一个WebSocketClient实例处理连接。崩溃偶发,堆栈追踪指向do_handshake方法。
我已检查对象生命周期:ssl_context_、resolver_、ws_等均为WebSocketClient类成员,且OrderBook对象生命周期长于WebSocketClient实例。
lldb终端信息:
* thread #5, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: 0x000000010003a28b adabtc`void boost::beast::websocket::stream<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>>, true>::do_handshake<void (*)(boost::beast::http::message<true, boost::beast::http::empty_body, boost::beast::http::basic_fields<std::__1::allocator<char>>>&)>(boost::beast::http::message<false, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char>>, boost::beast::http::basic_fields<std::__1::allocator<char>>>*, boost::core::basic_string_view<char>, boost::core::basic_string_view<char>, void (* const&)(boost::beast::http::message<true, boost::beast::http::empty_body, boost::beast::http::basic_fields<std::__1::allocator<char>>>&), boost::system::error_code&) + 843 adabtc`boost::beast::websocket::stream<boost::asio::ssl::stream<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>>, true>::do_handshake<void (*)(boost::beast::http::message<true, boost::beast::http::empty_body, boost::beast::http::basic_fields<std::__1::allocator<char>>>&)>:-> 0x10003a28b <+843>: vmovaps 0x40(%rax), %ymm0 0x10003a290 <+848>: leaq 0x2210(%rsp), %rax 0x10003a298 <+856>: vmovups %ymm0, (%rax) 0x10003a29c <+860>: movq %r13, %r12 Target 0: (adabtc) stopped.
内容的提问来源于stack exchange,提问作者Pedro Souto
相关产品推荐
相关产品推荐

