boost::asio Visual Studio 2013 年代码分段错误示例
boost::asio example code segmentation fault in Visual Studio 2013
我一直在尝试 运行 几个 boost::asio 示例。他们编译 link 没有问题,但是当他们试图在 io_service 上注册 async_accept 时,他们抛出一个分段错误。我附上了下面的代码。它未从 boost 文档中修改。
//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <ctime>
#include <iostream>
#include <string>
#include <memory>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
class session {
public:
session(boost::asio::io_service& io_service)
: socket_(io_service) {}
tcp::socket& socket() {
return socket_;
}
void start() {
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred) {
if (!error) {
boost::asio::async_write(socket_,
boost::asio::buffer(data_, bytes_transferred),
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else {
delete this;
}
}
void handle_write(const boost::system::error_code& error) {
if (!error) {
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else {
delete this;
}
}
private:
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server {
public:
server(boost::asio::io_service& io_service, short port)
: io_service_(io_service),
acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) {
session* new_session = new session(io_service_);
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));
}
void handle_accept(session* new_session,
const boost::system::error_code& error) {
if (!error) {
new_session->start();
new_session = new session(io_service_);
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));
}
else {
delete new_session;
}
}
private:
boost::asio::io_service& io_service_;
tcp::acceptor acceptor_;
};
回溯:
> gryphon.exe!boost::asio::detail::win_iocp_io_service::work_started() Line 96 C++ gryphon.exe!boost::asio::detail::win_iocp_socket_service_base::start_accept_op(boost::asio::detail::win_iocp_socket_service_base::base_implementation_type & impl, bool peer_is_open, boost::asio::detail::socket_holder & new_socket, int family, int type, int protocol, void * output_buffer, unsigned long address_length, boost::asio::detail::win_iocp_operation * op) Line 480 C++
gryphon.exe!boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::async_accept<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > >(boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::implementation_type & impl, boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & peer, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> * peer_endpoint, boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > & handler) Line 487 C++
gryphon.exe!boost::asio::socket_acceptor_service<boost::asio::ip::tcp>::async_accept<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp>,boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > >(boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::implementation_type & impl, boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & peer, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> * peer_endpoint, boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > && handler, void * __formal) Line 285 C++
gryphon.exe!boost::asio::basic_socket_acceptor<boost::asio::ip::tcp,boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >::async_accept<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp>,boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > >(boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & peer, boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > && handler, void * __formal) Line 1020 C++
gryphon.exe!server::server(boost::asio::io_service & io_service, short port) Line 75 C++
gryphon.exe!main() Line 32 C++
[External Code]
我之前让这段代码可以工作,但后来重新编译了 64 位 boost (address-model-64)。我认为这是错误的原因,但我不太了解 Visual Studio 或 Boost 的构建设置,无法知道。
编辑:
编译器选项
/GS /analyze- /W3 /Zc:wchar_t /I"src" /I"include" /I"C:\boost\boost_1_55_0" /ZI /Gm /Od /Fd"Debug\vc120.pdb" /fp:precise /D "_CRT_SECURE_NO_DEPRECATE" /D "_WIN32_WINDOWS" /D "WPCAP" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\gryphon.pch"
链接器选项
/OUT:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pdb" /DYNAMICBASE "Ws2_32.lib" "Packet.lib" "wpcap.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /INCREMENTAL /PGD:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\gryphon.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"lib" /LIBPATH:"C:\boost\boost_1_55_0\stage\lib" /TLBID:1
boost/stage/lib 目录包含 32 位预编译库。希望了解 32 bit/64 bit/multithreaded/static boost 库和 Windows 运行time 库之间的差异。
成功了。使用默认选项重建 Boost 并将 compiler/linker 选项更改为以下内容:(我认为删除 SUBSYSTEM /CONSOLE 标志是造成差异的原因)
编译器:
/GS /analyze- /W3 /Zc:wchar_t /I"src" /I"include" /I"C:\boost\boost_1_55_0\" /ZI /Gm /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /D "_CRT_SECURE_NO_DEPRECATE" /D "WPCAP" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\gryphon.pch"
链接器:
/OUT:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pdb" /DYNAMICBASE "Ws2_32.lib" "Packet.lib" "wpcap.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /INCREMENTAL /PGD:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\gryphon.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"lib" /LIBPATH:"C:\boost\boost_1_55_0\stage\lib" /TLBID:1
我一直在尝试 运行 几个 boost::asio 示例。他们编译 link 没有问题,但是当他们试图在 io_service 上注册 async_accept 时,他们抛出一个分段错误。我附上了下面的代码。它未从 boost 文档中修改。
//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <ctime>
#include <iostream>
#include <string>
#include <memory>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
class session {
public:
session(boost::asio::io_service& io_service)
: socket_(io_service) {}
tcp::socket& socket() {
return socket_;
}
void start() {
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred) {
if (!error) {
boost::asio::async_write(socket_,
boost::asio::buffer(data_, bytes_transferred),
boost::bind(&session::handle_write, this,
boost::asio::placeholders::error));
}
else {
delete this;
}
}
void handle_write(const boost::system::error_code& error) {
if (!error) {
socket_.async_read_some(boost::asio::buffer(data_, max_length),
boost::bind(&session::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else {
delete this;
}
}
private:
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server {
public:
server(boost::asio::io_service& io_service, short port)
: io_service_(io_service),
acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) {
session* new_session = new session(io_service_);
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));
}
void handle_accept(session* new_session,
const boost::system::error_code& error) {
if (!error) {
new_session->start();
new_session = new session(io_service_);
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));
}
else {
delete new_session;
}
}
private:
boost::asio::io_service& io_service_;
tcp::acceptor acceptor_;
};
回溯:
> gryphon.exe!boost::asio::detail::win_iocp_io_service::work_started() Line 96 C++ gryphon.exe!boost::asio::detail::win_iocp_socket_service_base::start_accept_op(boost::asio::detail::win_iocp_socket_service_base::base_implementation_type & impl, bool peer_is_open, boost::asio::detail::socket_holder & new_socket, int family, int type, int protocol, void * output_buffer, unsigned long address_length, boost::asio::detail::win_iocp_operation * op) Line 480 C++
gryphon.exe!boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::async_accept<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > >(boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::implementation_type & impl, boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & peer, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> * peer_endpoint, boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > & handler) Line 487 C++
gryphon.exe!boost::asio::socket_acceptor_service<boost::asio::ip::tcp>::async_accept<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp>,boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > >(boost::asio::detail::win_iocp_socket_service<boost::asio::ip::tcp>::implementation_type & impl, boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & peer, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> * peer_endpoint, boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > && handler, void * __formal) Line 285 C++
gryphon.exe!boost::asio::basic_socket_acceptor<boost::asio::ip::tcp,boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >::async_accept<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp>,boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > >(boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & peer, boost::_bi::bind_t<void,boost::_mfi::mf2<void,server,session *,boost::system::error_code const &>,boost::_bi::list3<boost::_bi::value<server *>,boost::_bi::value<session *>,boost::arg<1> > > && handler, void * __formal) Line 1020 C++
gryphon.exe!server::server(boost::asio::io_service & io_service, short port) Line 75 C++
gryphon.exe!main() Line 32 C++
[External Code]
我之前让这段代码可以工作,但后来重新编译了 64 位 boost (address-model-64)。我认为这是错误的原因,但我不太了解 Visual Studio 或 Boost 的构建设置,无法知道。
编辑: 编译器选项
/GS /analyze- /W3 /Zc:wchar_t /I"src" /I"include" /I"C:\boost\boost_1_55_0" /ZI /Gm /Od /Fd"Debug\vc120.pdb" /fp:precise /D "_CRT_SECURE_NO_DEPRECATE" /D "_WIN32_WINDOWS" /D "WPCAP" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\gryphon.pch"
链接器选项
/OUT:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pdb" /DYNAMICBASE "Ws2_32.lib" "Packet.lib" "wpcap.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /INCREMENTAL /PGD:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\gryphon.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"lib" /LIBPATH:"C:\boost\boost_1_55_0\stage\lib" /TLBID:1
boost/stage/lib 目录包含 32 位预编译库。希望了解 32 bit/64 bit/multithreaded/static boost 库和 Windows 运行time 库之间的差异。
成功了。使用默认选项重建 Boost 并将 compiler/linker 选项更改为以下内容:(我认为删除 SUBSYSTEM /CONSOLE 标志是造成差异的原因)
编译器:
/GS /analyze- /W3 /Zc:wchar_t /I"src" /I"include" /I"C:\boost\boost_1_55_0\" /ZI /Gm /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /D "_CRT_SECURE_NO_DEPRECATE" /D "WPCAP" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\gryphon.pch"
链接器:
/OUT:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pdb" /DYNAMICBASE "Ws2_32.lib" "Packet.lib" "wpcap.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /INCREMENTAL /PGD:"C:\Users\USER\Documents\Visual Studio 2013\Projects\gryphon\Debug\gryphon.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\gryphon.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"lib" /LIBPATH:"C:\boost\boost_1_55_0\stage\lib" /TLBID:1