Segfault cased by fn arg using seastar library

62 views Asked by At

In the code below, if I use local var called chunk, this program works as expected, but if I use same variable type but passed as a fn arg I'm getting segfault. I'm moving those objects so there shouldn't be a problem.

#include <seastar/core/app-template.hh>
#include <seastar/util/log.hh>
#include <seastar/core/coroutine.hh>
#include <seastar/core/sleep.hh>
#include <seastar/coroutine/maybe_yield.hh>
#include <seastar/coroutine/generator.hh>
#include <seastar/core/circular_buffer.hh>
#include <seastar/coroutine/all.hh>
#include <seastar/core/when_all.hh>
#include <seastar/core/reactor.hh>
#include <seastar/coroutine/parallel_for_each.hh>
#include <seastar/core/do_with.hh>

#include <stdexcept>
#include <vector>
#include <iostream>
#include <chrono>
#include <seastar/core/circular_buffer.hh>
#include <seastar/core/sleep.hh>
#include <seastar/coroutine/generator.hh>
#include <ranges>

seastar::coroutine::experimental::generator<char, seastar::circular_buffer>
generate_chars(coroutine::experimental::buffer_size_t, std::vector<char>&& buf) {
                std::ranges::sort(buf,ranges::greater());
    while (std::size(buf)) {
        char some_char = buf.back();
        buf.pop_back();
        co_yield some_char;
    }
}

future<> print_generated_chars(vector<char>&& chunk_)//instead of fn arg (which crashes) use local var chunk
{
    std::vector<char> chunk{'1','8','7','6','5','4','3','2'};//this will not cause segfault
    auto char_generator = generate_chars(coroutine::experimental::buffer_size_t{5},std::move(chunk));
    while (std::optional<char> c = co_await char_generator())
    {
        std::cout << "char: " << c.value() << '\n';
    }
}

int main(int argc, char** argv) {
    app_template app;

    return app.run(argc, argv, [&app] {
        
        std::vector<char> buf_1{'1','8','7','6','5','4','3','2'};
        return print_generated_chars(std::move(buf_1));
    });
}
1

There are 1 answers

2
Dmytro Ovdiienko On BEST ANSWER

I cannot post the code to the comment, so let me show it here.

I never worked with the co-routines and I do not know how the object lifetime works on that side. Maybe there are nuances. If you say that the local vector works, try changing your code into the following way:

future<> print_generated_chars(vector<char>&& chunk)
{
    // Take an ownership over the `chunk`
    auto local_chunk = std::move(chunk);

    auto char_generator = generate_chars(
       coroutine::experimental::buffer_size_t{5},
       std::move(local_chunk));

    while (std::optional<char> c = co_await char_generator())
    {
        std::cout << "char: " << c.value() << '\n';
    }
}