diff options
Diffstat (limited to 'misc/cgo/test/callback.go')
-rw-r--r-- | misc/cgo/test/callback.go | 43 |
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) + } + } +} |