Skip to content

cmd/compile: liveness / GC bug with variadic call #16996

@bradfitz

Description

@bradfitz

When writing a test for #16983, I encountered what looks like perhaps a liveness bug with variadic calls.

If I set "const useVariadic" to true below, the test fails (buf1 is never collected), but if I set it to false, buf1 is collected.

func twoReader(b1, b2 *bytes.Reader) Reader {
        return MultiReader(b1, b2)
}

func TestMultiReaderFreesExhaustedReaders(t *testing.T) {
        var mr Reader
        closed := make(chan struct{})
        {
                buf1 := bytes.NewReader([]byte("foo"))
                buf2 := bytes.NewReader([]byte("bar"))
                const useVariadic = true // set to true to see the bug; false to see the workaround                                                                          
                if useVariadic {
                        mr = MultiReader(buf1, buf2)
                } else {
                        mr = twoReader(buf1, buf2)
                }
                runtime.SetFinalizer(buf1, func(*bytes.Reader) {
                        close(closed)
                })
        }

        buf := make([]byte, 4)
        if n, err := ReadFull(mr, buf); err != nil || string(buf) != "foob" {
                t.Fatalf(`ReadFull = %d (%q), %v; want 3, "foo", nil`, n, buf[:n], err)
        }

        println("runtime.GC...")
        runtime.GC()
        println("waiting...")
        select {
        case <-closed:
        case <-time.After(5 * time.Second):
                t.Fatal("timeout waiting for collection of buf1")
        }

        if n, err := ReadFull(mr, buf[:2]); err != nil || string(buf[:2]) != "ar" {
                t.Fatalf(`ReadFull = %d (%q), %v; want 2, "ar", nil`, n, buf[:n], err)
        }
}

/cc @randall77 @josharian @minux @cherrymui

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions