runtime: only permit SetCgoTraceback to be called once

Accept a duplicate call, but nothing else.

Change-Id: Iec24bf5ddc3b0f0c559ad2158339aca698601743
Reviewed-on: https://go-review.googlesource.com/23692
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 96f154e2..80a5440 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -962,12 +962,21 @@
 // traceback function will only be called with the context field set
 // to zero.  If the context function is nil, then calls from Go to C
 // to Go will not show a traceback for the C portion of the call stack.
+//
+// SetCgoTraceback should be called only once, ideally from an init function.
 func SetCgoTraceback(version int, traceback, context, symbolizer unsafe.Pointer) {
 	if version != 0 {
 		panic("unsupported version")
 	}
 
+	if cgoTraceback != nil && cgoTraceback != traceback ||
+		cgoContext != nil && cgoContext != context ||
+		cgoSymbolizer != nil && cgoSymbolizer != symbolizer {
+		panic("call SetCgoTraceback only once")
+	}
+
 	cgoTraceback = traceback
+	cgoContext = context
 	cgoSymbolizer = symbolizer
 
 	// The context function is called when a C function calls a Go
@@ -978,6 +987,7 @@
 }
 
 var cgoTraceback unsafe.Pointer
+var cgoContext unsafe.Pointer
 var cgoSymbolizer unsafe.Pointer
 
 // cgoTracebackArg is the type passed to cgoTraceback.