Naios / continuable

C++14 asynchronous allocation aware futures (supporting then, exception handling, coroutines and connections)
https://naios.github.io/continuable/
MIT License
815 stars 44 forks source link

critical issue with nested continuables #65

Open Spongman opened 1 year ago

Spongman commented 1 year ago

@Naios

I think I have found a critical issue when awaiting nested continuables. It's a little hard to describe, but here's the code:

#include <string>
#include <thread>
#include <iostream>

#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/defer.hpp>

#include <coroutine>
#include <continuable/continuable.hpp>
#include <continuable/external/asio.hpp>

using namespace std;
using namespace chrono;
using namespace boost::asio;

struct Foo
{
    inline static int i__ = 0;
    volatile int i = i__++;

    Foo()                      { cout << i << " Foo()\n"; }
    Foo(const Foo&)            { cout << i << " Foo(const Foo&)\n"; }
    Foo(Foo&&)                 { cout << i << " Foo(Foo&&)\n"; }
    Foo& operator=(const Foo&) { cout << i << " operator=(const Foo&)\n"; return *this; }
    Foo& operator=(Foo&&)      { cout << i << " operator=(Foo&&)\n"; return *this; }
    ~Foo()                     { cout << i << " ~Foo()\n"; i = -i; }
};

int main() {

    io_context ctx;
    auto workGuard = make_work_guard(ctx);
    thread thd{[&]() { ctx.run(); }};
    Foo foo;

    defer(ctx, cti::use_continuable)
        .then([foo, &ctx]() -> cti::continuable<> {

            cout << "before: " << foo.i << "\n";

            boost::asio::steady_timer t1{ctx, milliseconds{10}};
            co_await t1.async_wait(cti::use_continuable);

            cout << "after: " << foo.i << "\n";
        })
        .apply(cti::transforms::wait());

    return 0;
}

The issue is concerning the lifetime of the lambda object that's passed to the then() clause. That lambda object has a Foo member (the foo capture), and that struct prints out the construction/deletion of the various copies of that member as the lambda object gets moved about.

and the important part of the output is:

22 Foo(Foo&&)       <-- instance #22 is constructed
21 ~Foo()
before: 22          <-- instance #22 is the one that's actually used during the invocation
22 ~Foo()           <-- instance #22 is deleted BEFORE the "after:" print statement
after: 1193563136   <-- the instance's `i` member is now corrupt

the local foo, and in fact the entire lambda object is being deleted during the handling of the nested timer callback:

#0  Foo::~Foo (this=0x7fffe62c14a0, __in_chrg=<optimized out>) at Main.cpp:79
#1  0x00000000004855fc in ~<lambda>(void) (this=0x7fffe62c14a0, __in_chrg=<optimized out>) at Main.cpp:115
#2  0x000000000048803c in cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)0, main(int, char**)::<lambda()>, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >::~callback_base(void) (this=0x7fffe62c14a0, __in_chrg=<optimized out>) at /home/piersh/staging/common/utils/continuable/detail/core/base.hpp:689
#3  0x000000000048826c in cti::detail::asio::promise_resolver<cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)0, main(int, char**)::<lambda()>, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >, cti::use_continuable_t<cti::detail::asio::map_default> >::~promise_resolver(void) (this=0x7fffe62c14a0, __in_chrg=<optimized out>) at /home/piersh/staging/common/utils/continuable/detail/external/asio.hpp:113
#4  0x0000000000488a6a in boost::asio::detail::binder0<cti::detail::asio::promise_resolver<cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)0, main(int, char**)::<lambda()>, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >, cti::use_continuable_t<cti::detail::asio::map_default> > >::~binder0(void) (this=0x7fffe62c14a0, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/bind_handler.hpp:32
#5  0x0000000000489c3f in boost::asio::detail::executor_op<boost::asio::detail::binder0<cti::detail::asio::promise_resolver<cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)0, main(int, char**)::<lambda()>, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >, cti::use_continuable_t<cti::detail::asio::map_default> > >, std::allocator<void>, boost::asio::detail::scheduler_operation>::do_complete(void *, boost::asio::detail::scheduler_operation *, const boost::system::error_code &, std::size_t) (owner=0xcfe200, base=0xcfa000) at /usr/include/boost/asio/detail/executor_op.hpp:73
Naios commented 11 months ago

Sorry for my late response. I have seen this issue as you created it. Thank you for your report. I will take a look on it in the following days.

Spongman commented 11 months ago

Were you able to reproduce and/or fix this? This issue is causing a bunch of use-after-free issues and segfaults for me, and it's becoming increasingly difficult to work around.

Naios commented 11 months ago

I have taken a look at your example and I had to fix a few issues with it:

#include <iostream>
#include <string>
#include <thread>
#include <list>
#include <continuable/continuable.hpp>

#include <asio/defer.hpp>
#include <asio/io_context.hpp>
#include <asio/steady_timer.hpp>

#include <coroutine>
#include <continuable/continuable.hpp>
#include <continuable/external/asio.hpp>

using namespace std;
using namespace chrono;
using namespace asio;

struct Foo {
  inline static int i__ = 0;
  volatile int i = i__++;

  Foo() {
    cout << i << " Foo()\n";
  }
  Foo(const Foo&) {
    cout << i << " Foo(const Foo&)\n";
  }
  Foo(Foo&&) noexcept {
    cout << i << " Foo(Foo&&)\n";
  }
  Foo& operator=(const Foo&) {
    cout << i << " operator=(const Foo&)\n";
    return *this;
  }
  Foo& operator=(Foo&&) noexcept {
    cout << i << " operator=(Foo&&)\n";
    return *this;
  }
  ~Foo() {
    cout << i << " ~Foo()\n";
    i = -i;
  }
};

io_context ctx;
std::list<asio::steady_timer> timers;

int main() {
  auto workGuard = make_work_guard(ctx);
  thread thd{[&]() {
    ctx.run();
  }};
  Foo foo;

  defer(ctx, cti::use_continuable)
      .then([&] {
        //! 1. invalid capture params in a coroutine lambda
        return [](Foo foo) -> cti::continuable<> {
          cout << "before: " << foo.i << "\n";

          co_await timers
              .emplace_back(ctx, milliseconds{10}) //! 2. timer lifetime moved out
              .async_wait(cti::use_continuable);

          cout << "after: " << foo.i << "\n";
          co_return; //! 3. co_return added 
        }(foo);
      })
      .apply(cti::transforms::wait());

  workGuard.reset();
  thd.join();
  return 0;
}

Could you confirm that your issue is still present in this example?

There are multiple points that could lead to your described behaviour:

  1. You are not allowed to capture any lambda parameters inside a coroutine lambda, this could lead to issues since continuable coroutines are initial suspending due to lazyness and the capture might not even be available anymore before the first co_await, see:
  2. Maybe the lifetime of the invoking timer inside the lamda which gets destructed as part of the timers invocation is an issue here.
  3. By definition you must add a co_return to every coroutine, otherwise this could lead to issues you are describing.

Is it possible to modify this example to reproduce the issue again?

pfeatherstone commented 11 months ago

When using coroutines with Asio wouldn't it be better to use Asio's built-in awaitable<> or coro<> objects ? Or have people found that the continuable<> object has less overhead ?

Naios commented 11 months ago

When using coroutines with Asio wouldn't it be better to use Asio's built-in awaitable<> or coro<> objects ? Or have people found that the continuable<> object has less overhead ?

In the two cases from the test code above, continuable should be completely zero overhead:

I think the awaitable from asio is zero overhead as well, so there is no advantage in using one over another from inside continuable coroutines.

pfeatherstone commented 11 months ago

Awesome. Do you know if continuable coroutines and asio coroutines mix well ?

Naios commented 11 months ago

Awesome. Do you know if continuable coroutines and asio coroutines mix well ?

For basic usage scenarios you can safely mix and match most coroutine libraries and their awaitable types.

If you have any further or follow-up questions open new ticket please. This ticket is meant for the discussion about this particular reported issue.

Naios commented 9 months ago

@Spongman can you confirm that removing the edge-cases in your example fixes the mentioned issues?

Spongman commented 5 months ago

here's a more minimal repro (that triggers use-after-free):

cti::continuable<> runAsync()
{
    co_await cti::make_continuable<void>([str = std::string{"foo"}](auto&& promise) mutable {
        promise.set_value();
    });
    co_return;
}

int main(int argc, char** argv)
{
    runAsync().apply(cti::transforms::wait());
    return 0;
}

can we get a make_continuable that forwards varargs since capturing is broken?

EDIT: wait, why is that broken? that lambda isn't a coroutine.


==93052==ERROR: AddressSanitizer: heap-use-after-free on address 0x60300002bfd0 at pc 0x0000004a581c bp 0x7fff018ffe10 sp 0x7fff018ffe00
WRITE of size 4 at 0x60300002bfd0 thread T0
    #0 0x4a581b in __gnu_cxx::__exchange_and_add(int volatile*, int) /opt/rh/devtoolset-11/root/usr/include/c++/11/ext/atomicity.h:66
    #1 0x4a581b in __gnu_cxx::__exchange_and_add_dispatch(int*, int) /opt/rh/devtoolset-11/root/usr/include/c++/11/ext/atomicity.h:101
    #2 0x4a581b in std::string::_Rep::_M_dispose(std::allocator<char> const&) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.h:3348
    #3 0x499a26 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.h:3768
    #4 0x475bd7 in ~<lambda> /home/user/release/tests/user/Main.cpp:152
    #5 0x475d21 in ~proxy_continuable /home/user/release/common/utils/continuable/detail/core/base.hpp:131
    #6 0x479d9b in ~chained_continuation /home/user/release/common/utils/continuable/detail/core/base.hpp:877
    #7 0x47c11c in ~continuable_base /home/user/release/common/utils/continuable/continuable-base.hpp:175
    #8 0x47d58a in invoke_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<>, cti::detail::base::callbacks::final_callback<> > /home/user/release/common/utils/continuable/detail/core/base.hpp:224
    #9 0x47d0cd in finalize_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::types::this_thread_executor_tag> > /home/user/release/common/utils/continuable/detail/core/base.hpp:1030
    #10 0x47c536 in done /home/user/release/common/utils/continuable/continuable-base.hpp:614
    #11 0x47ae10 in await_suspend /home/user/release/common/utils/continuable/detail/other/coroutines.hpp:129
    #12 0x477a17 in runAsync /home/user/release/tests/user/Main.cpp:155
    #13 0x49170f in std::__n4861::coroutine_handle<void>::resume() const /opt/rh/devtoolset-11/root/usr/include/c++/11/coroutine:126
    #14 0x4a1932 in auto cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}::operator()<cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/continuable/detail/other/coroutines.hpp:220
    #15 0x552f8c in decltype (((forward<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&>)({parm#1}))((forward<cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >)({parm#2}))) fu2::abi_400::detail::invocation::invoke<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) /home/user/release/common/utils/function2/function2.hpp:204
    #16 0x53d26a in fu2::abi_400::detail::type_erasure::invocation_table::function_trait<void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >)>::internal_invoker<fu2::abi_400::detail::type_erasure::box<false, cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>, std::allocator<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}> > >, true>::invoke(fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >) /home/user/release/common/utils/function2/function2.hpp:610
    #17 0x4d2db4 in decltype(auto) fu2::abi_400::detail::type_erasure::tables::vtable<fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long const&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(fu2::abi_400::detail::type_erasure::data_accessor*&&, unsigned long const&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/function2/function2.hpp:1018
    #18 0x4d30de in decltype(auto) fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) /home/user/release/common/utils/function2/function2.hpp:1240
    #19 0x4d31e9 in fu2::abi_400::detail::type_erasure::invocation_table::operator_impl<0ul, fu2::abi_400::detail::function<fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)>::operator()(cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >) /home/user/release/common/utils/function2/function2.hpp:798
    #20 0x4c7197 in cti::detail::erasure::continuation<>::operator()(cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >) /home/user/release/common/utils/continuable/detail/other/erasure.hpp:225
    #21 0x4d3ce7 in decltype (((forward<cti::detail::erasure::continuation<> >)({parm#1}))((forward<cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >)({parm#2}))) cti::detail::util::invoke<cti::detail::erasure::continuation<>, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >(cti::detail::erasure::continuation<>&&, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> >&&) /home/user/release/common/utils/continuable/detail/utility/util.hpp:221
    #22 0x4c83ff in void cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>::operator()<cti::detail::base::callbacks::final_callback<> >(cti::detail::base::callbacks::final_callback<>&&) /home/user/release/common/utils/continuable/detail/core/base.hpp:918
    #23 0x4c183c in decltype (((forward<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag> >)({parm#1}))((forward<cti::detail::base::callbacks::final_callback<> >)({parm#2}))) cti::detail::util::invoke<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::base::callbacks::final_callback<> >(cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>&&, cti::detail::base::callbacks::final_callback<>&&) /home/user/release/common/utils/continuable/detail/utility/util.hpp:221
    #24 0x4be55a in void cti::detail::base::invoke_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<>, cti::detail::base::callbacks::final_callback<> >(cti::continuable_base<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<> >&&, cti::detail::base::callbacks::final_callback<>&&) /home/user/release/common/utils/continuable/detail/core/base.hpp:224
    #25 0x4b8ef7 in void cti::detail::base::finalize_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>>(cti::continuable_base<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<> >&&) /home/user/release/common/utils/continuable/detail/core/base.hpp:1030
    #26 0x4b1595 in cti::continuable_base<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<> >::done() && /home/user/release/common/utils/continuable/continuable-base.hpp:614
    #27 0x4a48f3 in cti::result<> cti::detail::transforms::wait_relaxed<cti::detail::erasure::continuation<>, cti::detail::identity<>, cti::result<> >(cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >&&) /home/user/release/common/utils/continuable/detail/transforms/wait.hpp:143
    #28 0x498a62 in auto cti::detail::transforms::wait_and_unpack<cti::detail::erasure::continuation<>, cti::detail::identity<> >(cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >&&) /home/user/release/common/utils/continuable/detail/transforms/wait.hpp:160
    #29 0x49878c in auto cti::transforms::wait()::{lambda(auto:1&&)#1}::operator()<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> > >(cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/continuable/transforms/wait.hpp:76
    #30 0x498ead in auto cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >::apply<cti::transforms::wait()::{lambda(auto:1&&)#1}>(cti::transforms::wait()::{lambda(auto:1&&)#1}&&) && /home/user/release/common/utils/continuable/continuable-base.hpp:480
    #31 0x47886d in main /home/user/release/tests/user/Main.cpp:163
    #32 0x7fbeb0bb8554 in __libc_start_main (/lib64/libc.so.6+0x22554)
    #33 0x475a1a  (/home/user/release/tests/user/.libs/lt-user+0x475a1a)

0x60300002bfd0 is located 16 bytes inside of 28-byte region [0x60300002bfc0,0x60300002bfdc)
freed by thread T0 here:
    #0 0x7fbee419210f in operator delete(void*, unsigned long) (/lib64/libasan.so.6+0xb710f)
    #1 0x4be8ea in __gnu_cxx::new_allocator<char>::deallocate(char*, unsigned long) /opt/rh/devtoolset-11/root/usr/include/c++/11/ext/new_allocator.h:145
    #2 0x4b1fb8 in std::allocator<char>::deallocate(char*, unsigned long) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/allocator.h:199
    #3 0x4b1fb8 in std::string::_Rep::_M_destroy(std::allocator<char> const&) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.tcc:880
    #4 0x4a5867 in std::string::_Rep::_M_dispose(std::allocator<char> const&) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.h:3352
    #5 0x499a26 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.h:3768
    #6 0x477c5c in runAsync /home/user/release/tests/user/Main.cpp:158
    #7 0x49170f in std::__n4861::coroutine_handle<void>::resume() const /opt/rh/devtoolset-11/root/usr/include/c++/11/coroutine:126
    #8 0x479ac1 in operator()<> /home/user/release/common/utils/continuable/detail/other/coroutines.hpp:127
    #9 0x479b99 in partial_invoke_impl_shortcut<cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)> > /home/user/release/common/utils/continuable/detail/utility/util.hpp:178
    #10 0x479c76 in partial_invoke<0, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)> > /home/user/release/common/utils/continuable/detail/utility/util.hpp:211
    #11 0x479d24 in invoke_callback<cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)> > /home/user/release/common/utils/continuable/detail/core/base.hpp:284
    #12 0x47fef3 in operator()<cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::base::callbacks::final_callback<> > /home/user/release/common/utils/continuable/detail/core/base.hpp:374
    #13 0x48012f in on_executor<cti::detail::base::decoration::invoker<cti::detail::base::decoration::invoker_of(cti::detail::identity<void>)::<lambda(auto:24&&, auto:25&&, auto:26&& ...)>, cti::detail::identity<> >, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::base::callbacks::final_callback<> > /home/user/release/common/utils/continuable/detail/core/base.hpp:526
    #14 0x47f98d in operator() /home/user/release/common/utils/continuable/detail/core/base.hpp:642
    #15 0x47e938 in set_value /home/user/release/common/utils/continuable/detail/core/base.hpp:727
    #16 0x47daca in operator()<cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > > /home/user/release/tests/user/Main.cpp:154
    #17 0x47ea14 in invoke<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > > /home/user/release/common/utils/continuable/detail/utility/util.hpp:221
    #18 0x47e0da in operator()<cti::detail::base::callbacks::final_callback<> > /home/user/release/common/utils/continuable/detail/core/base.hpp:918
    #19 0x47d802 in invoke<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::types::this_thread_executor_tag>, cti::detail::base::callbacks::final_callback<> > /home/user/release/common/utils/continuable/detail/utility/util.hpp:221
    #20 0x47d57e in invoke_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<>, cti::detail::base::callbacks::final_callback<> > /home/user/release/common/utils/continuable/detail/core/base.hpp:224
    #21 0x47d0cd in finalize_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::awaiting::awaitable<cti::continuable_base<cti::detail::base::proxy_continuable<cti::detail::identity<>, runAsync(runAsync()::_Z8runAsyncv.Frame*)::<lambda(auto:87&&)> >, cti::detail::identity<> > >::await_suspend(std::__n4861::coroutine_handle<void>)::<lambda(auto:53&& ...)>, cti::detail::types::this_thread_executor_tag> > /home/user/release/common/utils/continuable/detail/core/base.hpp:1030
    #22 0x47c536 in done /home/user/release/common/utils/continuable/continuable-base.hpp:614
    #23 0x47ae10 in await_suspend /home/user/release/common/utils/continuable/detail/other/coroutines.hpp:129
    #24 0x477a17 in runAsync /home/user/release/tests/user/Main.cpp:155
    #25 0x49170f in std::__n4861::coroutine_handle<void>::resume() const /opt/rh/devtoolset-11/root/usr/include/c++/11/coroutine:126
    #26 0x4a1932 in auto cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}::operator()<cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/continuable/detail/other/coroutines.hpp:220
    #27 0x552f8c in decltype (((forward<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&>)({parm#1}))((forward<cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >)({parm#2}))) fu2::abi_400::detail::invocation::invoke<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) /home/user/release/common/utils/function2/function2.hpp:204
    #28 0x53d26a in fu2::abi_400::detail::type_erasure::invocation_table::function_trait<void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >)>::internal_invoker<fu2::abi_400::detail::type_erasure::box<false, cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>, std::allocator<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}> > >, true>::invoke(fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >) /home/user/release/common/utils/function2/function2.hpp:610
    #29 0x4d2db4 in decltype(auto) fu2::abi_400::detail::type_erasure::tables::vtable<fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long const&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(fu2::abi_400::detail::type_erasure::data_accessor*&&, unsigned long const&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/function2/function2.hpp:1018
    #30 0x4d30de in decltype(auto) fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) /home/user/release/common/utils/function2/function2.hpp:1240

previously allocated by thread T0 here:
    #0 0x7fbee41910a7 in operator new(unsigned long) (/lib64/libasan.so.6+0xb60a7)
    #1 0x4be8a7 in __gnu_cxx::new_allocator<char>::allocate(unsigned long, void const*) /opt/rh/devtoolset-11/root/usr/include/c++/11/ext/new_allocator.h:127
    #2 0x4b1c4e in std::allocator<char>::allocate(unsigned long) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/allocator.h:185
    #3 0x4b1c4e in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.tcc:1048
    #4 0x4b94dc in char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.tcc:610
    #5 0x4b224a in char* std::string::_S_construct_aux<char const*>(char const*, char const*, std::allocator<char> const&, std::__false_type) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.h:5180
    #6 0x4a5ab7 in char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.h:5201
    #7 0x49a135 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) /opt/rh/devtoolset-11/root/usr/include/c++/11/bits/basic_string.h:3663
    #8 0x477520 in runAsync /home/user/release/tests/user/Main.cpp:158
    #9 0x49170f in std::__n4861::coroutine_handle<void>::resume() const /opt/rh/devtoolset-11/root/usr/include/c++/11/coroutine:126
    #10 0x4a1932 in auto cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}::operator()<cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/continuable/detail/other/coroutines.hpp:220
    #11 0x552f8c in decltype (((forward<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&>)({parm#1}))((forward<cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >)({parm#2}))) fu2::abi_400::detail::invocation::invoke<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) /home/user/release/common/utils/function2/function2.hpp:204
    #12 0x53d26a in fu2::abi_400::detail::type_erasure::invocation_table::function_trait<void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >)>::internal_invoker<fu2::abi_400::detail::type_erasure::box<false, cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}>, std::allocator<cti::detail::base::proxy_continuable<cti::detail::identity<>, cti::detail::awaiting::promise_type<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >>::get_return_object()::{lambda(auto:1&&)#1}> > >, true>::invoke(fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >) /home/user/release/common/utils/function2/function2.hpp:610
    #13 0x4d2db4 in decltype(auto) fu2::abi_400::detail::type_erasure::tables::vtable<fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::data_accessor*, unsigned long const&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(fu2::abi_400::detail::type_erasure::data_accessor*&&, unsigned long const&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/function2/function2.hpp:1018
    #14 0x4d30de in decltype(auto) fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >::invoke<0ul, fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> > >(fu2::abi_400::detail::type_erasure::erasure<true, fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >&, cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >&&) /home/user/release/common/utils/function2/function2.hpp:1240
    #15 0x4d31e9 in fu2::abi_400::detail::type_erasure::invocation_table::operator_impl<0ul, fu2::abi_400::detail::function<fu2::abi_400::detail::config<true, false, cti::detail::erasure::continuation_capacity<> >, fu2::abi_400::detail::property<true, false, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)> >, void (cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >), bool (cti::is_ready_arg_t) const, cti::result<> (cti::unpack_arg_t)>::operator()(cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >) /home/user/release/common/utils/function2/function2.hpp:798
    #16 0x4c7197 in cti::detail::erasure::continuation<>::operator()(cti::promise_base<cti::detail::erasure::callback<>, cti::detail::identity<> >) /home/user/release/common/utils/continuable/detail/other/erasure.hpp:225
    #17 0x4d3ce7 in decltype (((forward<cti::detail::erasure::continuation<> >)({parm#1}))((forward<cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >)({parm#2}))) cti::detail::util::invoke<cti::detail::erasure::continuation<>, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> > >(cti::detail::erasure::continuation<>&&, cti::detail::base::callbacks::callback_base<cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag, cti::detail::base::callbacks::final_callback<> >&&) /home/user/release/common/utils/continuable/detail/utility/util.hpp:221
    #18 0x4c83ff in void cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>::operator()<cti::detail::base::callbacks::final_callback<> >(cti::detail::base::callbacks::final_callback<>&&) /home/user/release/common/utils/continuable/detail/core/base.hpp:918
    #19 0x4c183c in decltype (((forward<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag> >)({parm#1}))((forward<cti::detail::base::callbacks::final_callback<> >)({parm#2}))) cti::detail::util::invoke<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::base::callbacks::final_callback<> >(cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>&&, cti::detail::base::callbacks::final_callback<>&&) /home/user/release/common/utils/continuable/detail/utility/util.hpp:221
    #20 0x4be55a in void cti::detail::base::invoke_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<>, cti::detail::base::callbacks::final_callback<> >(cti::continuable_base<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<> >&&, cti::detail::base::callbacks::final_callback<>&&) /home/user/release/common/utils/continuable/detail/core/base.hpp:224
    #21 0x4b8ef7 in void cti::detail::base::finalize_continuation<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>>(cti::continuable_base<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<> >&&) /home/user/release/common/utils/continuable/detail/core/base.hpp:1030
    #22 0x4b1595 in cti::continuable_base<cti::detail::base::chained_continuation<cti::detail::identity<>, cti::detail::identity<>, (cti::detail::base::handle_results)1, (cti::detail::base::handle_errors)1, cti::detail::erasure::continuation<>, cti::detail::transforms::unsafe_unlocker<cti::result<> >, cti::detail::types::this_thread_executor_tag>, cti::detail::identity<> >::done() && /home/user/release/common/utils/continuable/continuable-base.hpp:614
    #23 0x4a48f3 in cti::result<> cti::detail::transforms::wait_relaxed<cti::detail::erasure::continuation<>, cti::detail::identity<>, cti::result<> >(cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >&&) /home/user/release/common/utils/continuable/detail/transforms/wait.hpp:143
    #24 0x498a62 in auto cti::detail::transforms::wait_and_unpack<cti::detail::erasure::continuation<>, cti::detail::identity<> >(cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >&&) /home/user/release/common/utils/continuable/detail/transforms/wait.hpp:160
    #25 0x49878c in auto cti::transforms::wait()::{lambda(auto:1&&)#1}::operator()<cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> > >(cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >&&) const /home/user/release/common/utils/continuable/transforms/wait.hpp:76
    #26 0x498ead in auto cti::continuable_base<cti::detail::erasure::continuation<>, cti::detail::identity<> >::apply<cti::transforms::wait()::{lambda(auto:1&&)#1}>(cti::transforms::wait()::{lambda(auto:1&&)#1}&&) && /home/user/release/common/utils/continuable/continuable-base.hpp:480
    #27 0x47886d in main /home/user/release/tests/user/Main.cpp:163
    #28 0x7fbeb0bb8554 in __libc_start_main (/lib64/libc.so.6+0x22554)```