My "fuzzer" (for lack of a better word) has become too clever for its
own good and started setting per-line debug hooks that error(),
producing too many spurious "crashes". So I locked it away in a
coroutine... and it immediately crashed. Oh well. :-)
A lucky random seed got me
.....coroutine.resume(table.unpack(debug.getregistry())).....,
which translates into:
-- begin test case --
A = coroutine.running( )
B = coroutine.create( function( ) coroutine.resume( A ) end )
coroutine.resume( B )
-- end test case --
Wrapping print() around the resumes, you get (with lua_assert #defined):
false cannot resume non-suspended coroutine
lua.debug: ldo.c:679: lua_resume: Assertion
`L->nCcalls == ((from) ? from->nCcalls : 0)' failed.
Aborted(134)
i.e. the resume of A fails with the expected error message, but the
resume of B runs into the assertion while returning.
(Previous problems in that corner: [1] (and maybe more))
Notably (& furthermore), coroutine.wrap will not hit the assertion,
instead the main thread (A) is claimed to be both dead _and_ alive:
-- begin test case #2 --
local co = coroutine
A = co.running( )
co.wrap( function( )
print( co.resume( A ) ) --> false, "cannot resume dead coroutine"
print( co.status( A ) ) --> "normal"
end )( )
-- end test case #2 --