aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/traceback.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2023-07-03 13:49:26 -0700
committerKeith Randall <khr@golang.org>2024-01-30 17:07:25 +0000
commita0d477cb6d3173c860583ccf7aa7919687bddbca (patch)
treec6f83e1044a20de95ad87a56fdc5b16f4802b587 /src/runtime/traceback.go
parent65f056d07ad1db7dd4fb23c4d35cf7b8bd0d6008 (diff)
downloadgo-a0d477cb6d3173c860583ccf7aa7919687bddbca.tar.xz
runtime: print exported methods from the runtime in tracebacks
We currently suppress runtime frames in tracebacks, except for exported functions. This CL also prints exported methods of exported types in tracebacks, for consistency. Change-Id: Ic65e7611621f0b210de5ae0c02b9d0a044f39fd6 Reviewed-on: https://go-review.googlesource.com/c/go/+/507736 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Diffstat (limited to 'src/runtime/traceback.go')
-rw-r--r--src/runtime/traceback.go28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 4ca4ac51ad..1c75c447d2 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -1133,10 +1133,32 @@ func showfuncinfo(sf srcFunc, firstFrame bool, calleeID abi.FuncID) bool {
// 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