简体   繁体   English

boost :: system :: error_code :: message()使用boost :: asio socket抛出访问冲突异常

[英]boost::system::error_code::message() throwing access violation exception with boost::asio socket

I am implementing a client application that has to make a small number of socket connections to hardware devices. 我正在实现一个客户端应用程序,它必须与硬件设备建立少量套接字连接。 I have broken down the problem to the following small code subset 我已将问题分解为以下小代码子集

boost::system::error_code ec;
std::string str_message = ec.message();  // no access violation before connect()
std::string str_port = "502";
std::string str_ip = "192.168.12.198";

boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(),str_ip,str_port);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ip::tcp::socket s(io_service);

ec = s.connect(*iterator,ec);
if (ec)
{
    // connection error of some kind.
    std::string str_debug = ec.message();  // BANG!!!!

}

I am using Embarcadero RAD studio XE4 C++ Builder and when I run the above code in the main VCL thread it works fine. 我正在使用Embarcadero RAD studio XE4 C ++ Builder,当我在主VCL线程中运行上面的代码时,它运行正常。 When I run it with multiple connections, I have the above code running in multiple instances of the TThread class and that is when I get into problems with an access violation - it appears that when the error_code is modified by the connect call, the internal member m_cat of the error_code instance becomes NULL and so when I call message() I get the access violation. 当我使用多个连接运行它时,我在TThread类的多个实例中运行上面的代码,这是当我遇到访问冲突的问题时 - 看来当connect调用修改error_code时,内部成员error_code实例的m_cat变为NULL,所以当我调用message()我得到访问冲突。 This happens even when I just have a single background thread running. 即使我只运行一个后台线程,也会发生这种情况。

Is it possible that my code above is simply not thread safe in the way I need to use it? 上面的代码是否有可能在我需要使用它的方式上不是线程安全的? I have tried to find out why this code won't run in a background thread, but cannot find anything about it. 我试图找出为什么这个代码不会在后台线程中运行,但找不到任何关于它的东西。

The boost version I am running is 1.50 as this is the integrated version that is used for building 64 bit applications in RAD studio. 我运行的升级版本是1.50,因为这是用于在RAD studio中构建64位应用程序的集成版本。

Has anyone else encountered this issue in a multithreaded setting (in Embarcadero or otherwise) and if so how did you resolve it? 有没有其他人在多线程设置中遇到此问题(在Embarcadero或其他方面),如果是这样,你是如何解决它的? Or is this class simply not safe to use in a multithreaded way? 或者这个类是不安全的以多线程方式使用?

This is kind of a long shot, but it might be worth a try: 这是一个很长的镜头,但它可能值得一试:

The system::error_code is made up of two entries: An error value and a category. system::error_code由两个条目组成:错误值和类别。 The error value is basically just an int , but the category is a Singleton . 错误值基本上只是一个int ,但类别是Singleton This is required because error categories are compared for equality based on pointer identities (ie. two categories are equal if and only if they point to the same category object). 这是必需的,因为基于指针标识比较错误类别的相等性(即,当且仅当它们指向相同的类别对象时,两个类别相等)。

The problem is that initialization of the category Singleton might not be thread-safe. 问题是Singleton类别的初始化可能不是线程安全的。 Asio uses the system_category , which is implemented in boost/libs/system/src/error_code.cpp . Asio使用system_category ,它在boost/libs/system/src/error_code.cpp For 1.50 the implementation looks like this: 对于1.50,实现看起来像这样:

BOOST_SYSTEM_DECL const error_category & system_category() BOOST_SYSTEM_NOEXCEPT
{
  static const system_error_category  system_category_const;
  return system_category_const;
}

This is guaranteed to be thread-safe on C++11 conforming compilers, but if your compiler does not implement thread-safe initialization of function-scope statics , this might break. 这保证在符合C ++ 11的编译器上是线程安全的,但是如果你的编译器没有实现函数范围静态的线程安全初始化 ,那么这可能会破坏。 You can easily verify this by tracing calls to this function and see if you observe a potential race. 您可以通过跟踪对此功能的调用轻松验证这一点,看看您是否观察到了潜在的竞争。

In multiple examples, they call io_service->run() in a thread: http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/futures/daytime_client.cpp 在多个示例中,他们在一个线程中调用io_service-> run(): http//www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/futures/daytime_client.cpp

I liked this one, with a ThreadPool: Thread pool using boost asio 我喜欢这个,使用了一个ThreadPool: 使用boost asio的线程池

Are you sure io_service->run() is called somewhere? 你确定在某处调用了io_service-> run()吗?

You must always be sure that iterator != boost::asio::ip::tcp::resolver::iterator() . 你必须始终确保iterator != boost::asio::ip::tcp::resolver::iterator()

From boost docs: 来自boost docs:

A default constructed iterator represents the end of the list. 默认构造的迭代器表示列表的结尾。

I bet it's the problem, connect() just breaks the stack due to invalid endpoint iterator. 我敢打赌这是问题, connect()只是因为无效的端点迭代器而破坏了堆栈。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从其他异常中分别捕获boost asio boost :: system :: error_code连接异常? - How to catch boost asio boost::system::error_code connect exception separatly from other exceptions? boost :: asio :: yield_context可以设置std :: error_code而不是boost :: system :: error_code吗? - Can boost::asio::yield_context set a std::error_code instead of boost::system::error_code? 使用boost :: asio :: write()boost :: system :: error_code永远不会设置 - Using boost::asio::write() boost::system::error_code never gets set 什么是升压系统error_code number 2 - What is boost system error_code number 2 GStreamer GError to boost::system::error_code? - GStreamer GError to boost::system::error_code? 无法将boost :: asio :: netdb :: errors转换为std :: error_code - Cannot convert boost::asio::netdb::errors to std::error_code 提升Asio tcp :: acceptor访问冲突异常 - Boost Asio tcp::acceptor access violation exception 当`boost :: asio :: ip :: tcp :: resolver :: resolve()`失败时,应该提供哪个`boost :: system :: error_code`值? - Which `boost::system::error_code` value should be provided when `boost::asio::ip::tcp::resolver::resolve()` fails? boost::system::error_code 和 boost::system::error_code::value() 有什么区别? - What is the difference between boost::system::error_code and boost::system::error_code::value()? boost :: system :: error_code :: message使用-stdlib = libc ++作为乱码 - boost::system::error_code::message comes out as gibberish with -stdlib=libc++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM