mirror of
https://github.com/golang/go
synced 2024-11-19 19:04:47 -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:
parent
a1a3d21355
commit
4b76a31c6d
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user