Commit 4b76a31c authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

runtime: don't crash in SetFinalizer if sizeof *x is zero

And document it explicitly, even though it already said
it wasn't guaranteed.

Fixes #6857

R=golang-dev, khr
CC=golang-dev
https://golang.org/cl/43580043
parent a1a3d213
......@@ -160,6 +160,9 @@ func funcentry_go(*Func) uintptr
// to depend on a finalizer to flush an in-memory I/O buffer such as a
// bufio.Writer, because the buffer would not be flushed at program exit.
//
// It is not guaranteed that a finalizer will run if the size of *x is
// zero bytes.
//
// A single goroutine runs all finalizers for a program, sequentially.
// If a finalizer must run for a long time, it should do so by starting
// a new goroutine.
......
......@@ -760,12 +760,15 @@ func SetFinalizer(obj Eface, finalizer Eface) {
runtime·printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.type->string);
goto throw;
}
ot = (PtrType*)obj.type;
if(ot->elem != nil && ot->elem->size == 0) {
return;
}
if(!runtime·mlookup(obj.data, &base, &size, nil) || obj.data != base) {
runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
goto throw;
}
nret = 0;
ot = (PtrType*)obj.type;
fint = nil;
if(finalizer.type != nil) {
if(finalizer.type->kind != KindFunc)
......
......@@ -100,6 +100,13 @@ func TestFinalizerInterfaceBig(t *testing.T) {
func fin(v *int) {
}
// Verify we don't crash at least. golang.org/issue/6857
func TestFinalizerZeroSizedStruct(t *testing.T) {
type Z struct{}
z := new(Z)
runtime.SetFinalizer(z, func(*Z) {})
}
func BenchmarkFinalizer(b *testing.B) {
const CallsPerSched = 1000
procs := runtime.GOMAXPROCS(-1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment