summaryrefslogtreecommitdiff
path: root/misc/cgo/test/callback.go
diff options
context:
space:
mode:
Diffstat (limited to 'misc/cgo/test/callback.go')
-rw-r--r--misc/cgo/test/callback.go43
1 files changed, 43 insertions, 0 deletions
diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go
index 4f5d3f855..b6e2e3c1c 100644
--- a/misc/cgo/test/callback.go
+++ b/misc/cgo/test/callback.go
@@ -12,7 +12,9 @@ import "C"
import (
"./backdoor"
+ "path"
"runtime"
+ "strings"
"testing"
"unsafe"
)
@@ -136,3 +138,44 @@ func testBlocking(t *testing.T) {
}
})
}
+
+// Test that the stack can be unwound through a call out and call back
+// into Go.
+func testCallbackCallers(t *testing.T) {
+ pc := make([]uintptr, 100)
+ n := 0
+ name := []string{
+ "test.goCallback",
+ "runtime.cgocallbackg",
+ "runtime.cgocallback_gofunc",
+ "return",
+ "runtime.cgocall",
+ "test._Cfunc_callback",
+ "test.nestedCall",
+ "test.testCallbackCallers",
+ "test.TestCallbackCallers",
+ "testing.tRunner",
+ "runtime.goexit",
+ }
+ nestedCall(func() {
+ n = runtime.Callers(2, pc)
+ })
+ if n != len(name) {
+ t.Errorf("expected %d frames, got %d", len(name), n)
+ }
+ for i := 0; i < n; i++ {
+ f := runtime.FuncForPC(pc[i])
+ if f == nil {
+ t.Fatalf("expected non-nil Func for pc %p", pc[i])
+ }
+ fname := f.Name()
+ // Remove the prepended pathname from automatically
+ // generated cgo function names.
+ if strings.HasPrefix(fname, "_") {
+ fname = path.Base(f.Name()[1:])
+ }
+ if fname != name[i] {
+ t.Errorf("expected function name %s, got %s", name[i], fname)
+ }
+ }
+}