aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.goc
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2014-04-02 10:19:28 +0400
committerDmitriy Vyukov <dvyukov@google.com>2014-04-02 10:19:28 +0400
commitf4ef6977ffab6c741b059d03147562e7c5901c0c (patch)
tree7db769ddff45aa197b5da8d269e72eb4970f135f /src/pkg/runtime/malloc.goc
parent383963b50622d9e0a28a3deb75aba8533e5ad949 (diff)
downloadgo-f4ef6977ffab6c741b059d03147562e7c5901c0c.tar.xz
runtime: ignore pointers to global objects in SetFinalizer
Update #7656 LGTM=rsc R=rsc, iant CC=golang-codereviews https://golang.org/cl/82560043
Diffstat (limited to 'src/pkg/runtime/malloc.goc')
-rw-r--r--src/pkg/runtime/malloc.goc11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc
index c463abb110..6fee8932df 100644
--- a/src/pkg/runtime/malloc.goc
+++ b/src/pkg/runtime/malloc.goc
@@ -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;
}
}