-
Notifications
You must be signed in to change notification settings - Fork 951
Memory corruption with scheduler=coroutines #2101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This appears to be unrelated to #2041 because it doesn't trigger an assertion failure in LLVM. Which means it's probably a real bug in TinyGo. |
Some digging:
The code here does seem to trigger the LLVM bug in #2041 but monkey-patching those issues doesn't fix it. So I think it's something else. |
Indeed. I get the same panic with
So it's not related to the GC. I suspect it's the combination of |
I think the
This one doesn't crash, but does show that
|
@deadprogram This bug is not limited to wasm. The most recent reproducer fails built on my Mac:
Not |
Here's another reduced test case with the contents of the
building with
produces
Both flog addresses should be the same. Edit: Just noticed this particular reducer only triggers with |
This is starting to seem like a lifetime isse. Adding either of these lines (uncommented)
after the call to Oddly, adding |
I have managed to reduce this bug even further. I believe this is still the same bug: package main
import "time"
func main() {
n := byte(23)
foo(&n)
}
func foo(n *byte) {
time.Sleep(1)
println("n is", *n)
} This should print 23, but it prints 1 in TinyGo:
The problem is that @niaow I'm fairly certain this is a bug in the coroutine conversion pass. It should convert parents of async functions that contain an alloca instruction that is alive between suspension points (or, conservatively, any function that contains an |
So, more specifically: the |
Yes, that would also be a possible solution. It seems slightly more risky to me, but I don't see a reason why it wouldn't work. |
Alright, I can add a check and convert to a coroutine in that case I guess. |
Either seems fine by me, if it fixes the bug. Hopefully the new asincify solution will make all of this obsolete. |
Well, this appears to include an addional problem. After switching over to coroutine transform, the coroutine lowering seems to not be moving the alloca into the frame. |
Oh. . . there is actually another bug with tail call lowering I guess. . . |
So it appears that all coroutine tail calls are implemented incorrectly. |
I've minimized the reproducer in #2101 (comment) a bit more (now that I know about using
This fails even after the patch from #2117. Building with
on my Mac. Adding |
That first bug is just a code quality issue, it shouldn't result in an actual bug. The second one to me appears like a Clang issue, although I'm not entirely sure. In the end, the only real way to investigate it is to shrink it down and investigate the IR. However, as I found in #1720, I believe there are fundamental issues in the way we lower goroutines in WebAssembly so maybe a much bigger change is needed to fix it properly. |
As I've mentioned, it seems like asyncify is the way forward in the short term, and the wasm stack-switching proposal the longer term solution. |
coroutines were removed a while ago. |
Produces the following output:
This was run with tinygo build from
dev
and the patch from #2100 .I've tried to shrink this down as much as I can. The
println
inside the closure generates a nil-pointer crash when trying to restoreflog
from the coroutine context.It's possible this will go away with llvm12 with the coroutine changes.
This bug is not present when built with -gc=leaking, but I think that's because the llvm coroutine logic needs more function calls (which are present when there's more logic being inserted for allocations, etc) rather than an issue with the conservative collector itself. (We have a similar issue present in a larger codebase that is built with the leaking collector.)
The text was updated successfully, but these errors were encountered: