Commit 354fa9a8 authored by Austin Clements's avatar Austin Clements

runtime: simplify stack walk in panicwrap

panicwrap currently uses runtime.Callers and runtime.CallersFrames to
find the name of its caller. Simplify this by using getcallerpc.

This will be important for #16723, since to fix that we're going to
make CallersFrames skip the wrapper method, which is exactly what
panicwrap needs to see.

Change-Id: Icb0776d399966e31595f3ee44f980290827e32a6
Reviewed-on: https://go-review.googlesource.com/45411
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 229aaac1
...@@ -126,34 +126,31 @@ func printany(i interface{}) { ...@@ -126,34 +126,31 @@ func printany(i interface{}) {
//go:linkname stringsIndexByte strings.IndexByte //go:linkname stringsIndexByte strings.IndexByte
func stringsIndexByte(s string, c byte) int func stringsIndexByte(s string, c byte) int
// called from generated code // panicwrap generates a panic for a call to a wrapped value method
// with a nil pointer receiver.
//
// It is called from the generated wrapper code.
func panicwrap() { func panicwrap() {
pc := make([]uintptr, 1) pc := getcallerpc()
n := Callers(2, pc) name := funcname(findfunc(pc))
if n == 0 {
throw("panicwrap: Callers failed")
}
frames := CallersFrames(pc)
frame, _ := frames.Next()
name := frame.Function
// name is something like "main.(*T).F". // name is something like "main.(*T).F".
// We want to extract pkg ("main"), typ ("T"), and meth ("F"). // We want to extract pkg ("main"), typ ("T"), and meth ("F").
// Do it by finding the parens. // Do it by finding the parens.
i := stringsIndexByte(name, '(') i := stringsIndexByte(name, '(')
if i < 0 { if i < 0 {
throw("panicwrap: no ( in " + frame.Function) throw("panicwrap: no ( in " + name)
} }
pkg := name[:i-1] pkg := name[:i-1]
if i+2 >= len(name) || name[i-1:i+2] != ".(*" { if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
throw("panicwrap: unexpected string after package name: " + frame.Function) throw("panicwrap: unexpected string after package name: " + name)
} }
name = name[i+2:] name = name[i+2:]
i = stringsIndexByte(name, ')') i = stringsIndexByte(name, ')')
if i < 0 { if i < 0 {
throw("panicwrap: no ) in " + frame.Function) throw("panicwrap: no ) in " + name)
} }
if i+2 >= len(name) || name[i:i+2] != ")." { if i+2 >= len(name) || name[i:i+2] != ")." {
throw("panicwrap: unexpected string after type name: " + frame.Function) throw("panicwrap: unexpected string after type name: " + name)
} }
typ := name[:i] typ := name[:i]
meth := name[i+2:] meth := name[i+2:]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment