1
0
mirror of https://github.com/golang/go synced 2024-11-19 21:14:43 -07:00

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
This commit is contained in:
Brad Fitzpatrick 2013-12-17 14:18:58 -08:00
parent a1a3d21355
commit 4b76a31c6d
3 changed files with 14 additions and 1 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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)