}
}
}
+
+// For TestRuntimePanic: test a panic in the runtime package without
+// involving the testing harness.
+func init() {
+ if os.Getenv("GO_TEST_RUNTIME_PANIC") == "1" {
+ defer func() {
+ if r := recover(); r != nil {
+ // We expect to crash, so exit 0
+ // to indicate failure.
+ os.Exit(0)
+ }
+ }()
+ runtime.PanicForTesting(nil, 1)
+ // We expect to crash, so exit 0 to indicate failure.
+ os.Exit(0)
+ }
+}
+
+func TestRuntimePanic(t *testing.T) {
+ testenv.MustHaveExec(t)
+ cmd := exec.Command(os.Args[0], "-test.run=TestRuntimePanic")
+ cmd.Env = append(cmd.Env, "GO_TEST_RUNTIME_PANIC=1")
+ out, err := cmd.CombinedOutput()
+ t.Logf("%s", out)
+ if err == nil {
+ t.Error("child process did not fail")
+ } else if want := "runtime.unexportedPanicForTesting"; !bytes.Contains(out, []byte(want)) {
+ t.Errorf("output did not contain expected string %q", want)
+ }
+}
func Getg() *G {
return getg()
}
+
+//go:noinline
+func PanicForTesting(b []byte, i int) byte {
+ return unexportedPanicForTesting(b, i)
+}
+
+//go:noinline
+func unexportedPanicForTesting(b []byte, i int) byte {
+ return b[i]
+}
var indexError = error(errorString("index out of range"))
+// The panicindex, panicslice, and panicdivide functions are called by
+// code generated by the compiler for out of bounds index expressions,
+// out of bounds slice expressions, and division by zero. The
+// panicdivide (again), panicoverflow, panicfloat, and panicmem
+// functions are called by the signal handler when a signal occurs
+// indicating the respective problem.
+//
+// Since panicindex and panicslice are never called directly, and
+// since the runtime package should never have an out of bounds slice
+// or array reference, if we see those functions called from the
+// runtime package we turn the panic into a throw. That will dump the
+// entire runtime stack for easier debugging.
+
func panicindex() {
+ if hasprefix(funcname(findfunc(getcallerpc())), "runtime.") {
+ throw(string(indexError.(errorString)))
+ }
panicCheckMalloc(indexError)
panic(indexError)
}
var sliceError = error(errorString("slice bounds out of range"))
func panicslice() {
+ if hasprefix(funcname(findfunc(getcallerpc())), "runtime.") {
+ throw(string(sliceError.(errorString)))
+ }
panicCheckMalloc(sliceError)
panic(sliceError)
}