http_client构造函数(Casablanca SDK)内部崩溃

时间:2019-05-13 15:01:09

标签: rest c++11 casablanca

我正在尝试使用卡萨布兰卡使用REST api。 我一直在关注Microsoft教程,但是我却遇到崩溃了,但无法弄清。

我正在将Visual Studio 2017与C ++ 11一起使用

我编写了一个GetRequest()函数,该函数在一个新的空项目中使用时可以正常工作,但是当我尝试在我的项目中使用它时(这个非常大的项目有数百万行代码)。 我在文件xmemory0第118行的http_client的构造函数中崩溃了。

const uintptr_t _Ptr_container = _Ptr_user[-1];

这是指向调用栈的链接:https://i.imgur.com/lBm0Hv7.png

void RestManager::GetRequest()
{
    auto fileStream = std::make_shared<ostream>();

    // Open stream to output file.
    pplx::task<void> requestTask = fstream::open_ostream(U("results.html")).then([=](ostream outFile)
    {
        *fileStream = outFile;

        // Create http_client to send the request.
        http_client client(U("XXX/XXX.svc/"));

        // Build request URI and start the request.
        uri_builder builder(U("/IsLive"));
        builder.append_query(U("q"), U("cpprestsdk github"));
        return client.request(methods::GET, builder.to_string());
    })

        // Handle response headers arriving.
        .then([=](http_response response)
    {
        printf("Received response status code:%u\n", response.status_code());

        // Write response body into the file.
    return response.body().read_to_end(fileStream->streambuf());
    })    

        // Close the file stream.
        .then([=](size_t)
    {
        return fileStream->close();
    });

    // Wait for all the outstanding I/O to complete and handle any exceptions
    try
    {
        requestTask.wait();
    }
    catch (const std::exception &e)
    {
        printf("Error exception:%s\n", e.what());
    }

}

编辑:我只想补充一下http_client构造函数是问题。无论我作为参数发送什么,它总是崩溃在里面。

更奇怪的是,当我只创建一个调用此函数的main()时,它不会崩溃。 我想这一定是由于某些内存问题引起的,但是我不知道该如何调试。 有人会对此有想法吗?

谢谢,祝你有美好的一天!

2 个答案:

答案 0 :(得分:2)

我在ubuntu上遇到了类似的问题。它可以在空项目中工作,但在放入现有的大型项目中会随机崩溃,抱怨内存损坏。

事实证明,现有项目已加载专有库,该库在内部使用cpprestsdk(casablanca)。即使cpprestsdk是静态链接,其符号仍将导出为弱符号。因此,要么我的代码崩溃,要么专有库崩溃。

理想情况下,我的项目可以分为几个库,并用RTLD_LOCAL加载它们,以避免符号冲突。但是我项目中的专有库只接受RTLD_GLOBAL,否则会崩溃...因此导入顺序和标志变得很重要:

dlopen("my-lib-uses-cpprest", RTLD_LOCAL); //To avoid polluting the global
dlopen("proprietary-lib-with-built-in-cpprest", RTLD_GLOBAL); //In my case, this lib must be global
dlopen("another-lib-uses-cpprest", RTLD_DEEPBIND); //To avoid being affected by global

“它可能永远不会关心任何人。”

我同意。

答案 1 :(得分:0)

我想这个问题是非常具体的,可能永远不会涉及到任何人,但是我仍将更新我发现的所有问题。

在这个项目中,我们使用的是自定义分配器,如果我没记错的话,就不可能将我们的自定义分配器提供给这个lib,这会导致许多随机崩溃。

修复此问题的一个好方法是对该库使用静态版本,但是,由于我们使用了大量动态库,因此我们无法使用此选项。

如果您愿意,我建议您使用libcurl和Rapidjson,虽然使用起来有点困难,但是您可以实现相同的目标。