【问题标题】:Crash in boost::coroutine library when used alongside boost::property_tree XML parser与 boost::property_tree XML 解析器一起使用时 boost::coroutine 库中的崩溃
【发布时间】:2016-10-04 01:08:29
【问题描述】:

我正在使用 Simple-Web-Server 库创建简单的 Web 服务,用于将 XML 转换为 JSON,反之亦然。反过来,它使用了几个 boost 库以及其中的 boost::coroutine。对于 XMLJSON 转换,我使用 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-Server1.4.2版本。

【问题讨论】:

  • 那是很多代码。看起来好像 Simple-Web-Server 不是生产就绪代码。我已经看了一段时间了,但是有很多活动部件,很难掌握。
  • Web 服务不再与不再使用 boost::coroutineSimple-Web-Serverversion 2.0 崩溃,但我想知道这是否是 boost::coroutineboost::property_tree 之间的某种不兼容,因为我过去两者都使用过,并且我在@中描述了类似的奇怪崩溃987654326@ 问题。那时候我没有把它和boost::property_tree XML解析联系起来,但现在我认为可能有一些联系。

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


【解决方案1】:

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 访问它)

【讨论】:

  • 很好的答案!我等了这么久。在我以前的公司中,我们在生产代码中遇到了类似的问题,描述为 here,然后我们没有意识到问题出在 RapidXML 中。
猜你喜欢
  • 2017-12-27
  • 2018-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 2015-10-15
  • 1970-01-01
  • 2013-03-03
相关资源
最近更新 更多