【问题标题】:ASIO Debug Error in MSVC Debug Build- No error in Release BuildMSVC 调试版本中的 ASIO 调试错误 - 发布版本中没有错误
【发布时间】:2018-09-12 14:34:54
【问题描述】:

使用 ASIO 的简单 tcp 客户端会导致调用 abort() 以进行调试构建。 Release 构建中的相同应用程序可以正常工作而不会引发错误。编译器是 Visual Studio 2017。

将调试器附加到应用程序不会提供任何附加信息。

下面显示了一个将端口作为命令行参数连接到服务器并立即断开连接的演示示例。

我有什么办法可以在调试版本中避免这个错误?

#include <memory>
#include <string>
#include <iostream>

#include "asio.hpp"

using asio::ip::tcp;

class Client {
  std::unique_ptr<asio::io_service> io_service_ = nullptr;
  std::unique_ptr<tcp::socket> sock_ = nullptr;

 public:
  Client() {
    io_service_ = std::make_unique<asio::io_service>();
    sock_ = std::make_unique<tcp::socket>(*io_service_);
  }
  void connect(std::string hostname, unsigned int port) {
    auto resolver = tcp::resolver(*io_service_);
    auto query = tcp::resolver::query(hostname, std::to_string(port));
    auto endpoint_iter = resolver.resolve(query);
    asio::connect(*sock_, endpoint_iter);
  }
};

int main(int argc, char* argv[]) {
  try {
    auto port = std::stoi(argv[1]);
    Client client;
    client.connect("localhost", port);
  } catch (std::exception& e) {
    std::cout << "\n" << e.what();
  }
}

【问题讨论】:

  • “将调试器附加到应用程序不会提供任何附加信息。”怎么没有?在abort() 处总是至少有一个堆栈跟踪。您甚至可以在库函数本身上设置断点,以防调试器捕获它为时已晚
  • @sehe 当我有 try-catch 块时没有跟踪,当我取出 try-catch 块时,我得到了跟踪 > sClient.exe!invoke_main() 第 79 行 C++ sClient.exe !__scrt_common_main_seh() 第 288 行 C++ sClient.exe!__scrt_common_main() 第 331 行 C++ sClient.exe!mainCRTStartup() 第 17 行 C++ kernel32.dll!00007ff95ae43034() 未知 ntdll.dll!00007ff95b071431() 未知 我不明白。

标签: visual-c++ boost-asio


【解决方案1】:

这些的常见来源是调试迭代器。它们是你的朋友,因为它们会警告你程序中的未定义行为。

在这个程序中,我没有看到这样的问题:

#include <iostream>
#include <memory>
#include <string>

#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class Client {
    std::unique_ptr<boost::asio::io_service> io_service_ = nullptr;
    std::unique_ptr<tcp::socket> sock_ = nullptr;

  public:
    Client() {
        io_service_ = std::make_unique<boost::asio::io_service>();
        sock_ = std::make_unique<tcp::socket>(*io_service_);
    }
    void connect(std::string hostname, unsigned int port) {
        auto resolver = tcp::resolver(*io_service_);
        auto query = tcp::resolver::query(hostname, std::to_string(port));
        auto endpoint_iter = resolver.resolve(query);
        boost::asio::connect(*sock_, endpoint_iter);
    }
};

int main() {
    try {
        Client client;
        client.connect("localhost", 6767);
    } catch (std::exception &e) {
        std::cout << "\n" << e.what();
    }
}

主要区别在于我没有使用argv[1]。由于您没有检查argc,您实际上是否为调试配置传递了参数?

【讨论】:

  • 我实际上是在将参数传递给调试配置,并在调试时单步执行代码时查看值。客户端是导致此错误的更大库的一部分,我已隔离到这部分,服务器使用随机端口,因此将其作为客户端的命令行参数很方便。我对调试迭代器了解不多,快速文档搜索here 表明我可以设置_ITERATOR_DEBUG_LEVEL=0。设置此项并没有抑制问题。
  • 祝你好运进一步隔离错误!
猜你喜欢
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-16
  • 2010-10-27
  • 2020-08-02
相关资源
最近更新 更多