]> Cypherpunks repositories - gostls13.git/commitdiff
misc/cgo/test: get uintptr, not pointer, from dlopen
authorIan Lance Taylor <iant@golang.org>
Fri, 2 Feb 2018 13:38:08 +0000 (05:38 -0800)
committerIan Lance Taylor <iant@golang.org>
Fri, 2 Feb 2018 18:42:10 +0000 (18:42 +0000)
The dlopen function returns an opaque handle, and it is possible for
it to look like a Go pointer, causing garbage collector and cgo
confusion.

Fixes #23663

Change-Id: Id080e2bbcee8cfa7ac4a457a927f96949eb913f8
Reviewed-on: https://go-review.googlesource.com/91596
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
misc/cgo/test/issue4029.c
misc/cgo/test/issue4029.go

index eab36834501ff78389eb00ad127a074c1f65b09e..7205c5a5a2505250adf5bfa54909f37bb27b8798 100644 (file)
@@ -4,6 +4,25 @@
 
 // +build !windows
 
+#include <stdint.h>
+#include <dlfcn.h>
+
+// Write our own versions of dlopen/dlsym/dlclose so that we represent
+// the opaque handle as a Go uintptr rather than a Go pointer to avoid
+// garbage collector confusion.  See issue 23663.
+
+uintptr_t dlopen4029(char* name, int flags) {
+       return (uintptr_t)(dlopen(name, flags));
+}
+
+uintptr_t dlsym4029(uintptr_t handle, char* name) {
+       return (uintptr_t)(dlsym((void*)(handle), name));
+}
+
+int dlclose4029(uintptr_t handle) {
+       return dlclose((void*)(handle));
+}
+
 void call4029(void *arg) {
        void (*fn)(void) = arg;
        fn();
index 5789b99ef67034f4644bac0aa9186e40675a1cf4..8e468d367d1ec9d9ad21ae6b564e64293bc93057 100644 (file)
@@ -7,10 +7,15 @@
 package cgotest
 
 /*
+#include <stdint.h>
 #include <dlfcn.h>
 #cgo linux LDFLAGS: -ldl
 
-extern void call4029(void *arg);
+extern uintptr_t dlopen4029(char*, int);
+extern uintptr_t dlsym4029(uintptr_t, char*);
+extern int dlclose4029(uintptr_t);
+
+extern void call4029(uintptr_t arg);
 */
 import "C"
 
@@ -51,15 +56,15 @@ func test4029(t *testing.T) {
 }
 
 func loadThySelf(t *testing.T, symbol string) {
-       this_process := C.dlopen(nil, C.RTLD_NOW)
-       if this_process == nil {
+       this_process := C.dlopen4029(nil, C.RTLD_NOW)
+       if this_process == 0 {
                t.Error("dlopen:", C.GoString(C.dlerror()))
                return
        }
-       defer C.dlclose(this_process)
+       defer C.dlclose4029(this_process)
 
-       symbol_address := C.dlsym(this_process, C.CString(symbol))
-       if symbol_address == nil {
+       symbol_address := C.dlsym4029(this_process, C.CString(symbol))
+       if symbol_address == 0 {
                t.Error("dlsym:", C.GoString(C.dlerror()))
                return
        }