Boost 链 post 在 accessing/inserting 值时导致分段错误
Boost strands post causing segmentation faults when accessing/inserting values
我目前正在编写一个网络结构,它只让一个服务器监听它自己的链,很简单。每当调用链来调用函数并且该函数调用 class 中的任何成员时,就会发生分段错误。
有一些例外,但值得注意的是这些分段错误发生在
- tcp::acceptor myAcceptor(my_io_service, myEndpoint)
- mySockets.insert(...)
现在我可以轻松交换 myAcceptor 并将其放在构造函数的初始化列表中并将其视为 class 成员,但我想避免这种情况。
那么接下来要验证我的说法是什么?我最近的尝试是检查 mySockets 的大小,我应该注意,它是一个 map。我在调用 myStrand.post(...) 之前 检查了大小,并检查了函数调用中的大小。这是我注意到的。
mySockets 映射大小:
- 在 post 之前:0(未插入任何内容,太棒了!)
- 在函数调用中,由 post 调用:999929272 (Ughhhh)
似乎有些东西变了,但到底是什么?它是否创建了一个新实例,但奇怪的是这不是 0 吗?它不可能丢失地址,因为这肯定会导致分段错误,不是吗?
这就是我目前在调试过程中所处的位置。
目标
最终目标是能够访问 post 链中的 mySockets 和 my_io_service。
布局流程
这解释了布局,好的ol代码在下面
- 通过 io_service
创建 'work'
- 通过调用 .运行()
启动 io_service
- 创建 TCP 服务器
- 将参数分配给 class 成员类型
- 调用 myStrand.post(...) 调用服务器,侦听连接客户端
- 等待客户端连接等
我选择了详细说明问题的代码示例。
头文件
using boost::asio::ip::tcp;
bool amIConnected = false;
boost::asio::io_service::strand myStrand;
boost::asio::io_service& my_io_service;
std::map<std::string, std::shared_ptr<tcp::socket>> mySockets;
tcp::acceptor myAcceptor
源文件
ConstructorStuff::ConstructorStuff(boost::asio::io_service& the_service) :
myStrand(the_service),
my_io_service(the_service),
myAcceptor(the_service, tcp::endpoint(tcp::v4(), 1337))
{}
void ConstructorStuff::CreateTheServer()
{
amIConnected = true;
// std::cout << mySockets.size() << std::endl; Returns 0
mStrand.post(std::bind(&ConstructorStuff::ListenForConnection, this));
}
void ConstructorStuff::ListenForConection()
{
// std::cout << mySockets.size() << std::endl; Crazy size
tcp::acceptor tryAgain(my_io_service, tcp::endpoint(tcp::v4(), 1338)); // Just to showcase the error doesn't just occur through mySockets.
}
调用ConstructorStuff的地方
void SetupServer()
{
ConstructorStuff stuff(some_service);
stuff.CreateTheServer();
}
这调用了上面的函数
ServiceStarter spinup(service);
spinup.Start(); // Just queues reference_service.run()
std::shared_ptr<SomeClass> server_interface(new SomeClass ( service ));
server_interface->SetupServer();
boost::this_thread::sleep(boost::posix_time::seconds(20));
server_interface->Cancel(); // Just another function that kills the server.
有什么建议就太好了!
旁注:
- 头文件中的任何附加值,例如 myPort,在 CreateTheServer() 中初始化为 1337,然后在 ListenForConnection() 突然不一样了。
- 为了让任何可能会问的人放心,这些值可以在外部链中访问,从而将这个问题锁定为我遇到的与链相关的问题。
编辑
我添加了两个新的源文件。我能展示的内容非常有限,但这应该足以说明问题。
问题出在SetupServer
,其中stuff
是局部变量,所以在调用CreateTheServer
之后,stuff
被io_service::run
处理程序销毁并在某处mStrand.post(std::bind(&ConstructorStuff::ListenForConnection, this));
发布的被删除的对象调用。然后 std::cout << mySockets.size() << std::endl;
打印出奇怪的结果——这是一个未定义行为的简单示例。
我目前正在编写一个网络结构,它只让一个服务器监听它自己的链,很简单。每当调用链来调用函数并且该函数调用 class 中的任何成员时,就会发生分段错误。
有一些例外,但值得注意的是这些分段错误发生在
- tcp::acceptor myAcceptor(my_io_service, myEndpoint)
- mySockets.insert(...)
现在我可以轻松交换 myAcceptor 并将其放在构造函数的初始化列表中并将其视为 class 成员,但我想避免这种情况。
那么接下来要验证我的说法是什么?我最近的尝试是检查 mySockets 的大小,我应该注意,它是一个 map。我在调用 myStrand.post(...) 之前 检查了大小,并检查了函数调用中的大小。这是我注意到的。
mySockets 映射大小:
- 在 post 之前:0(未插入任何内容,太棒了!)
- 在函数调用中,由 post 调用:999929272 (Ughhhh)
似乎有些东西变了,但到底是什么?它是否创建了一个新实例,但奇怪的是这不是 0 吗?它不可能丢失地址,因为这肯定会导致分段错误,不是吗?
这就是我目前在调试过程中所处的位置。
目标
最终目标是能够访问 post 链中的 mySockets 和 my_io_service。
布局流程
这解释了布局,好的ol代码在下面
- 通过 io_service 创建 'work'
- 通过调用 .运行() 启动 io_service
- 创建 TCP 服务器
- 将参数分配给 class 成员类型
- 调用 myStrand.post(...) 调用服务器,侦听连接客户端
- 等待客户端连接等
我选择了详细说明问题的代码示例。
头文件
using boost::asio::ip::tcp;
bool amIConnected = false;
boost::asio::io_service::strand myStrand;
boost::asio::io_service& my_io_service;
std::map<std::string, std::shared_ptr<tcp::socket>> mySockets;
tcp::acceptor myAcceptor
源文件
ConstructorStuff::ConstructorStuff(boost::asio::io_service& the_service) :
myStrand(the_service),
my_io_service(the_service),
myAcceptor(the_service, tcp::endpoint(tcp::v4(), 1337))
{}
void ConstructorStuff::CreateTheServer()
{
amIConnected = true;
// std::cout << mySockets.size() << std::endl; Returns 0
mStrand.post(std::bind(&ConstructorStuff::ListenForConnection, this));
}
void ConstructorStuff::ListenForConection()
{
// std::cout << mySockets.size() << std::endl; Crazy size
tcp::acceptor tryAgain(my_io_service, tcp::endpoint(tcp::v4(), 1338)); // Just to showcase the error doesn't just occur through mySockets.
}
调用ConstructorStuff的地方
void SetupServer()
{
ConstructorStuff stuff(some_service);
stuff.CreateTheServer();
}
这调用了上面的函数
ServiceStarter spinup(service);
spinup.Start(); // Just queues reference_service.run()
std::shared_ptr<SomeClass> server_interface(new SomeClass ( service ));
server_interface->SetupServer();
boost::this_thread::sleep(boost::posix_time::seconds(20));
server_interface->Cancel(); // Just another function that kills the server.
有什么建议就太好了!
旁注:
- 头文件中的任何附加值,例如 myPort,在 CreateTheServer() 中初始化为 1337,然后在 ListenForConnection() 突然不一样了。
- 为了让任何可能会问的人放心,这些值可以在外部链中访问,从而将这个问题锁定为我遇到的与链相关的问题。
编辑
我添加了两个新的源文件。我能展示的内容非常有限,但这应该足以说明问题。
问题出在SetupServer
,其中stuff
是局部变量,所以在调用CreateTheServer
之后,stuff
被io_service::run
处理程序销毁并在某处mStrand.post(std::bind(&ConstructorStuff::ListenForConnection, this));
发布的被删除的对象调用。然后 std::cout << mySockets.size() << std::endl;
打印出奇怪的结果——这是一个未定义行为的简单示例。