]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: ignore pointers to global objects in SetFinalizer
authorDmitriy Vyukov <dvyukov@google.com>
Wed, 2 Apr 2014 06:19:28 +0000 (10:19 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Wed, 2 Apr 2014 06:19:28 +0000 (10:19 +0400)
Update #7656

LGTM=rsc
R=rsc, iant
CC=golang-codereviews
https://golang.org/cl/82560043

src/pkg/runtime/malloc.goc
src/pkg/runtime/mfinal_test.go

index c463abb1108d99874454a9c715fedfa8d97cfb20..6fee8932df3755b0fd0eff111e1e4ffddf0dc851 100644 (file)
@@ -885,11 +885,20 @@ func SetFinalizer(obj Eface, finalizer Eface) {
        // because we use &runtime·zerobase for all such allocations.
        if(ot->elem != nil && ot->elem->size == 0)
                return;
+       // The following check is required for cases when a user passes a pointer to composite literal,
+       // but compiler makes it a pointer to global. For example:
+       //      var Foo = &Object{}
+       //      func main() {
+       //              runtime.SetFinalizer(Foo, nil)
+       //      }
+       // See issue 7656.
+       if((byte*)obj.data < runtime·mheap.arena_start || runtime·mheap.arena_used <= (byte*)obj.data)
+               return;
        if(!runtime·mlookup(obj.data, &base, &size, nil) || obj.data != base) {
                // As an implementation detail we allow to set finalizers for an inner byte
                // of an object if it could come from tiny alloc (see mallocgc for details).
                if(ot->elem == nil || (ot->elem->kind&KindNoPointers) == 0 || ot->elem->size >= TinySize) {
-                       runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
+                       runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block (%p)\n", obj.data);
                        goto throw;
                }
        }
index 41213138d2a9f0ae2fcd3dffe410f4b8073746dc..6b53888ab6a276ab8947bf8e0837cf56dfb7297e 100644 (file)
@@ -216,3 +216,24 @@ func TestEmptyString(t *testing.T) {
 }
 
 var ssglobal string
+
+// Test for issue 7656.
+func TestFinalizerOnGlobal(t *testing.T) {
+       runtime.SetFinalizer(Foo1, func(p *Object1) {})
+       runtime.SetFinalizer(Foo2, func(p *Object2) {})
+       runtime.SetFinalizer(Foo1, nil)
+       runtime.SetFinalizer(Foo2, nil)
+}
+
+type Object1 struct {
+       Something []byte
+}
+
+type Object2 struct {
+       Something byte
+}
+
+var (
+       Foo2 = &Object2{}
+       Foo1 = &Object1{}
+)