自己写了一些带coroutine的for循环,发现stackoverflow。
怀疑是不是有symmetric transfer的问题,对着Lewis Baker的那篇博文比较,的确如此。
改成symmetric transfer的形式后,仍然crash,导致自我怀疑好几天。
gdb跟踪发现仍然有递归导致stackoverflow,怀疑gcc是不是对symmetric transfer的支持有问题。
于是换到godbolt下面测试。
我用的是gcc-14.2,但即使换成最新版gcc-15.1,如果不开优化,仍然crash。
gcc编译必须要开-O2以上优化才能通过,clang比较正常,不开优化就能通过。
系统很敏感,你可以解码如下base63+1编码获得到godbolt代码测试的链接:
echo aHR0cHM6Ly9nb2Rib2x0Lm9yZy96L2FjNTdUem9yZgo= | base63+1 -d
认识这个字符串格式的就懂,把63+1换成那个神秘的数字。
测试代码如下:
#include <coroutine>
#include <iostream>
#include <utility>
struct task
{
struct promise_type
{
task get_return_object() noexcept
{
return task{std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_always initial_suspend() noexcept
{
return {};
}
void return_void() noexcept {}
void unhandled_exception() noexcept
{
std::terminate();
}
struct final_awaiter
{
bool await_ready() noexcept
{
return false;
}
std::coroutine_handle<> await_suspend(std::coroutine_handle<promise_type> h) noexcept
{
return h.promise().continuation;
}
void await_resume() noexcept {}
};
final_awaiter final_suspend() noexcept
{
return {};
}
std::coroutine_handle<> continuation;
};
~task()
{
if (m_coro)
m_coro.destroy();
}
struct awaiter
{
bool await_ready() noexcept
{
return false;
}
std::coroutine_handle<> await_suspend(std::coroutine_handle<> continuation) noexcept
{
m_coro.promise().continuation = continuation;
return m_coro;
}
void await_resume() noexcept {}
explicit awaiter(std::coroutine_handle<promise_type> h) noexcept
: m_coro(h)
{}
std::coroutine_handle<promise_type> m_coro;
};
awaiter operator co_await() && noexcept
{
return awaiter{m_coro};
}
explicit task(std::coroutine_handle<promise_type> h) noexcept
: m_coro(h)
{}
std::coroutine_handle<promise_type> m_coro;
void resume() noexcept
{
if (m_coro)
awaiter(m_coro).await_suspend(std::noop_coroutine()).resume();
}
};
task completes_synchronously()
{
co_return;
}
task loop_synchronously(int count)
{
std::cout << "start looping of " << count << " times" << std::endl;
for (int i = 0; i < count; ++i) {
co_await completes_synchronously();
}
std::cout << "finished" << std::endl;
}
int main()
{
loop_synchronously(100000000).resume();
return 0;
}
--
修改:allegro FROM 182.129.63.*
FROM 182.129.63.*