Skip to content
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

implement runtime safety check for resuming not-suspended async function #3469

Closed
emekoi opened this issue Oct 17, 2019 · 4 comments
Closed
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. stage1 The process of building from source via WebAssembly and the C backend.
Milestone

Comments

@emekoi
Copy link
Contributor

emekoi commented Oct 17, 2019

the following code causes a stack overflow in zig when run and a segfault when trying to print the stack trace.

fn foo() void {
    var f = async bar(@frame());
    unreachable;
}

fn bar(frame: anyframe) void {
    suspend {
        resume frame;
    }
    unreachable;
}

test "test" {
    _ = async foo();
}
@andrewrk
Copy link
Member

Let's follow the control flow of this example:

    _ = async foo();
////////////////////
    var f = async bar(@frame());
////////////////////
        resume frame; // note that `frame` is not suspended; this is illegal behavior
////////////////////

Expected output from this is safety crash for resuming a function which is not suspended. So this is a case of missing debug safety.

segfault when trying to print the stack trace.

That part is #1616.

@andrewrk andrewrk added this to the 0.6.0 milestone Oct 23, 2019
@andrewrk andrewrk added enhancement Solving this issue will likely involve adding new logic or components to the codebase. stage1 The process of building from source via WebAssembly and the C backend. labels Oct 23, 2019
@andrewrk andrewrk changed the title async function call causes stack overflow implement runtime safety check for resuming not-suspended async function Oct 23, 2019
@emekoi
Copy link
Contributor Author

emekoi commented Oct 23, 2019

ohhh, so await and suspend are suspend points but resume and async are not?

@andrewrk
Copy link
Member

andrewrk commented Oct 23, 2019

Yes that's correct. Think of resume and async as function calls, which return when the target frame suspends.

@andrewrk
Copy link
Member

Here's what it looks like now after the changes that I made locally:

Test [1/1] test "test"...resumed a non-suspended function
/home/andy/dev/zig/build/test2.zig:1:1: 0x20d85a in foo (test)
fn foo() void {
^
/home/andy/dev/zig/build/test2.zig:8:9: 0x20dfc9 in bar (test)
        resume frame;
        ^
/home/andy/dev/zig/build/test2.zig:2:13: 0x20d81f in foo (test)
    var f = async bar(@frame());
            ^
/home/andy/dev/zig/build/test2.zig:14:9: 0x20d5b5 in test "test" (test)
    _ = async foo();
        ^
/home/andy/dev/zig/lib/std/special/test_runner.zig:20:25: 0x24212b in std.special.main (test)
        if (test_fn.func()) |_| {
                        ^
/home/andy/dev/zig/lib/std/special/start.zig:204:37: 0x240f35 in std.special.posixCallMainAndExit (test)
            const result = root.main() catch |err| {
                                    ^
/home/andy/dev/zig/lib/std/special/start.zig:102:5: 0x240daf in std.special._start (test)
    @noInlineCall(posixCallMainAndExit);
    ^

Tests failed. Use the following command to reproduce the failure:
/home/andy/dev/zig/build/zig-cache/o/S-bSJ_0MUe7bZJWDvBu7TKpo5B6w3B112oXlFrD2S7m3MOErvTAyzLjKPnpuxuAe/test

I'll push this after the tests pass.

@mlugg mlugg added this to Safety Aug 22, 2024
@mlugg mlugg moved this to Done in Safety Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. stage1 The process of building from source via WebAssembly and the C backend.
Projects
Status: Done
Development

No branches or pull requests

2 participants