c++ - 与 boost::property_tree XML 解析器一起使用时 boost::coroutine 库崩溃

标签 c++ boost boost-asio boost-propertytree boost-coroutine

我正在使用 Simple-Web-Server用于创建将 XML 转换为 JSON 的简单 Web 服务的库,反之亦然。反过来,它使用了几个 boost 库以及其中的 boost::coroutine。对于 XML<->JSON 转换,我使用 boost::property_tree 库进行中间表示。这是代码:

#include <iostream>
#include <sstream>

#include <server_http.hpp>

#define BOOST_SPIRIT_THREADSAFE
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>

using namespace std;
using namespace boost::property_tree;

using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;

int main()
{
  HttpServer server(8080, 1);

  server.resource["^/json_to_xml$"]["POST"] = [](auto& response, auto request) {
    try
    {
      ptree pt;
      read_json(request->content, pt);
      ostringstream json, xml;
      write_json(json, pt);
      clog << "JSON request content:" << endl << json.str() << endl;
      write_xml(xml, pt, xml_writer_make_settings<ptree::key_type>(' ', 1u));
      clog << "XML response content:" << endl << xml.str() << endl;
      response << "HTTP/1.1 200 OK\r\nContent-Length: " << xml.str().length() << "\r\n\r\n" << xml.str();
    }
    catch(const exception& e)
    {
      cerr << "Error:" << endl << e.what() << endl;
      response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n" << e.what();
    }
  };

  server.resource["^/xml_to_json$"]["POST"] = [](auto& response, auto request) {
    try
    {
      ptree pt;
      read_xml(request->content, pt, xml_parser::trim_whitespace | xml_parser::no_comments);
      ostringstream xml, json;
      write_xml(xml, pt, xml_writer_make_settings<ptree::key_type>(' ', 1u));
      clog << "XML request content:" << endl << xml.str() << endl;
      write_json(json, pt);
      clog << "JSON response content: " << endl << json.str() << endl;
      response << "HTTP/1.1 200 OK\r\nContent-Length: " << json.str().length() << "\r\n\r\n" << json.str();
    }
    catch(const exception& e)
    {
      cerr << "Error:" << endl << e.what() << endl;
      response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n" << e.what();
    }
  };

  server.start();

  return 0;
}

JSONXML 的转换工作正常,但相反会导致程序崩溃。当我没有在服务器的回调中使用 boost::property_treeXML 解析器时,程序运行良好。 Here是执行的结果。 HereGDB 回溯。最后 hereValgrind 输出。

使用的 boost 库版本是 1.58.0 但最新版本 1.61.0 观察到相同的结果。使用 Simple-Web-Server 版本 1.4.2

最佳答案

read_xml() 可能会溢出协程的堆栈;见here关于一个类似的崩溃,追溯到 rapidxml 解析器中的一个 64K 堆栈变量。

编辑。总结一下链接……问题的要点是,埋在 read_xml 中的 rapidxml 解析器在堆栈上分配了 64K,这溢出了 Linux 上的 8K 默认协程堆栈。您可以尝试两件事……要么强制该堆栈变量变小,例如,

#define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE 512
#include <boost/property_tree/xml_parser.hpp>

或者在生成协程时分配更大的堆栈(如果可以通过 Simple-Web-Server 访问它)

关于c++ - 与 boost::property_tree XML 解析器一起使用时 boost::coroutine 库崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37623314/

相关文章:

c++ - 如何知道 boost::asio::ip::tcp::iostream 上没有可用数据?

c++ - 带有 boost::asio 的 ThreadPool 不退出?

c++ - 堆叠 Cg 着色器

c++ - 如何在 C++ 中计算不同的数字基数?

c++ - CppDepend 中的圈复杂度

c++ - 使用边缘容器 boost astar_search

c++ - 扫描目录以从 C++ 加载 Python 插件

c++ - 如何使笔记本的标签文本方向垂直(在 gtkmm 中)

c++ - 至少一个字符的正则表达式

c++ - 用于异步 boost.asio 操作时 std::string 的生命周期管理