package main import ( "encoding/binary" "runtime" "testing" "unsafe" ) // Keep each recursive frame live so the stack must grow past its initial allocation. // //go:noinline func growStack(depth byte) byte { var frame [4096]byte frame[0] = depth if depth > 0 { frame[1] = growStack(depth - 1) } runtime.KeepAlive(&frame) return frame[0] + frame[1] } func TestPinnedRequest(t *testing.T) { if unsafe.Sizeof(tableInfo{}) != 84 { t.Fatal("native getsockopt layout differs from ipt_getinfo") } done := make(chan [2]uint64, 1) go func() { request := newReplace(config{inbound: 4143, outbound: 4140}, 5) defer request.pins.Unpin() growStack(32) runtime.GC() done <- [2]uint64{binary.NativeEndian.Uint64(request.data[88:]), request.address()} }() addresses := <-done if addresses[0] != addresses[1] { t.Fatalf("counter address moved: %x -> %x", addresses[0], addresses[1]) } }