Skip to content

Crash in 2.10.5: Waking up from hibernate causes std::logic_error in running HTTP requests on unix #857

Closed
@reneme

Description

@reneme

I noticed a pretty consistent crash with std::logic_error: uninitialized stream object when putting my Mac or Linux machine into hibernate mode while cpprest has HTTP requests in flight. The actual crash seems to happen as soon as the machine wakes up from >1 min hibernation. It seems that the error was introduced with v2.10.5.

I used the program below to reproduce the problem (adapted BingRequest example). When executed it sends 10 concurrent requests to bing.com in an endless loop. While running, I put the laptop into sleep-mode for about one minute and observe a pretty consistent crash when waking it up again.

#include <array>

#include <cpprest/http_client.h>
#include <cpprest/rawptrstream.h>

using namespace utility;
using namespace web::http;
using namespace web::http::client;
using namespace concurrency::streams;

std::shared_ptr<http_client> gClient;

pplx::task<void> doRequest() {
    auto sink_buffer = std::make_shared<std::array<uint8_t, 1048576>>();
    auto sink = rawptr_stream<uint8_t>::open_ostream(sink_buffer->data(),
                                                     sink_buffer->size());
    const auto uri = uri_builder(U("/search"))
                        .append_query(U("q"), U("foobar"))
                        .to_string();

    printf("requesting...\n");

    return gClient->request(methods::GET, uri)
        .then([sink](http_response response) {
            printf("response with HTTP %u\n", response.status_code());
            return response.body().read_to_end(sink.streambuf());
        })
        .then([sink, sink_buffer](size_t s) {
            printf("found %lu bytes in response body\n", s);
            return sink.close();
        });
}

int main(int argc, char *args[])
{
    const unsigned int parallel_requests = 10;

    printf("creating client...\n");
    http_client_config cfg;
    gClient = std::make_shared<http_client>(U("https://www.bing.com/"), cfg);

    while (true) {
        std::vector<pplx::task<void>> ts;
        ts.reserve(parallel_requests);

        for (unsigned int i = 0; i < parallel_requests; ++i) {
            ts.emplace_back(doRequest());
        }

        for (auto &t : ts) {
            try {
                t.get();
            } catch (const http_exception &ex) {
                printf("ignoring http exception: %s\n", ex.what());
            }
        }

        printf("---\n");
    }

    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions