// We expect to crash, so exit 0 to indicate failure.
                os.Exit(0)
        }
+       if os.Getenv("GO_TEST_RUNTIME_NPE_READMEMSTATS") == "1" {
+               runtime.ReadMemStats(nil)
+               os.Exit(0)
+       }
+       if os.Getenv("GO_TEST_RUNTIME_NPE_FUNCMETHOD") == "1" {
+               var f *runtime.Func
+               _ = f.Entry()
+               os.Exit(0)
+       }
+
 }
 
 func TestRuntimePanic(t *testing.T) {
        }
 }
 
+func TestTracebackRuntimeFunction(t *testing.T) {
+       testenv.MustHaveExec(t)
+       cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=TestTracebackRuntimeFunction"))
+       cmd.Env = append(cmd.Env, "GO_TEST_RUNTIME_NPE_READMEMSTATS=1")
+       out, err := cmd.CombinedOutput()
+       t.Logf("%s", out)
+       if err == nil {
+               t.Error("child process did not fail")
+       } else if want := "runtime.ReadMemStats"; !bytes.Contains(out, []byte(want)) {
+               t.Errorf("output did not contain expected string %q", want)
+       }
+}
+
+func TestTracebackRuntimeMethod(t *testing.T) {
+       testenv.MustHaveExec(t)
+       cmd := testenv.CleanCmdEnv(exec.Command(os.Args[0], "-test.run=TestTracebackRuntimeMethod"))
+       cmd.Env = append(cmd.Env, "GO_TEST_RUNTIME_NPE_FUNCMETHOD=1")
+       out, err := cmd.CombinedOutput()
+       t.Logf("%s", out)
+       if err == nil {
+               t.Error("child process did not fail")
+       } else if want := "runtime.(*Func).Entry"; !bytes.Contains(out, []byte(want)) {
+               t.Errorf("output did not contain expected string %q", want)
+       }
+}
+
 // Test that g0 stack overflows are handled gracefully.
 func TestG0StackOverflow(t *testing.T) {
        testenv.MustHaveExec(t)
 
 
 // isExportedRuntime reports whether name is an exported runtime function.
 // It is only for runtime functions, so ASCII A-Z is fine.
-// TODO: this handles exported functions but not exported methods.
 func isExportedRuntime(name string) bool {
-       const n = len("runtime.")
-       return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
+       // Check and remove package qualifier.
+       n := len("runtime.")
+       if len(name) <= n || name[:n] != "runtime." {
+               return false
+       }
+       name = name[n:]
+       rcvr := ""
+
+       // Extract receiver type, if any.
+       // For example, runtime.(*Func).Entry
+       i := len(name) - 1
+       for i >= 0 && name[i] != '.' {
+               i--
+       }
+       if i >= 0 {
+               rcvr = name[:i]
+               name = name[i+1:]
+               // Remove parentheses and star for pointer receivers.
+               if len(rcvr) >= 3 && rcvr[0] == '(' && rcvr[1] == '*' && rcvr[len(rcvr)-1] == ')' {
+                       rcvr = rcvr[2 : len(rcvr)-1]
+               }
+       }
+
+       // Exported functions and exported methods on exported types.
+       return len(name) > 0 && 'A' <= name[0] && name[0] <= 'Z' && (len(rcvr) == 0 || 'A' <= rcvr[0] && rcvr[0] <= 'Z')
 }
 
 // elideWrapperCalling reports whether a wrapper function that called