]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use srcFunc for showframe
authorAustin Clements <austin@google.com>
Mon, 6 Feb 2023 03:02:03 +0000 (22:02 -0500)
committerAustin Clements <austin@google.com>
Fri, 10 Mar 2023 17:18:29 +0000 (17:18 +0000)
Since srcFunc can represent information for either an real text
function or an inlined function, this means we no longer have to
synthesize a fake _func just to call showframe on an inlined frame.

This is cleaner and also eliminates the one case where _func values
live in the heap. This will let us mark them NotInHeap, which will in
turn eliminate pesky write barriers in the traceback rewrite.

For #54466.

Change-Id: Ibf5e24d01ee4bf384c825e1a4e2922ef444a438e
Reviewed-on: https://go-review.googlesource.com/c/go/+/466097
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/runtime/traceback.go

index d04bbf2d5789d7117756f104e1613af4ecafe023..e873ac74bea301993cb2981c061e84b9f958dd7e 100644 (file)
@@ -376,22 +376,16 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                        // If there is inlining info, print the inner frames.
                        if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
                                inltree := (*[1 << 20]inlinedCall)(inldata)
-                               var inlFunc _func
-                               inlFuncInfo := funcInfo{&inlFunc, f.datap}
                                for {
                                        ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, nil)
                                        if ix < 0 {
                                                break
                                        }
 
-                                       // Create a fake _func for the
-                                       // inlined function.
-                                       inlFunc.nameOff = inltree[ix].nameOff
-                                       inlFunc.funcID = inltree[ix].funcID
-                                       inlFunc.startLine = inltree[ix].startLine
+                                       sf := srcFunc{f.datap, inltree[ix].nameOff, inltree[ix].startLine, inltree[ix].funcID}
 
-                                       if (flags&_TraceRuntimeFrames) != 0 || showframe(inlFuncInfo, gp, nprint == 0, inlFuncInfo.funcID, calleeFuncID) {
-                                               name := funcname(inlFuncInfo)
+                                       if (flags&_TraceRuntimeFrames) != 0 || showframe(sf, gp, nprint == 0, calleeFuncID) {
+                                               name := sf.name()
                                                file, line := funcline(f, tracepc)
                                                print(name, "(...)\n")
                                                print("\t", file, ":", line, "\n")
@@ -402,7 +396,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                                        tracepc = frame.fn.entry() + uintptr(inltree[ix].parentPc)
                                }
                        }
-                       if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, f.funcID, calleeFuncID) {
+                       if (flags&_TraceRuntimeFrames) != 0 || showframe(f.srcFunc(), gp, nprint == 0, calleeFuncID) {
                                // Print during crash.
                                //      main(0x1, 0x2, 0x3)
                                //              /home/rsc/go/src/runtime/x.go:23 +0xf
@@ -692,7 +686,7 @@ func printcreatedby(gp *g) {
        // Show what created goroutine, except main goroutine (goid 1).
        pc := gp.gopc
        f := findfunc(pc)
-       if f.valid() && showframe(f, gp, false, funcID_normal, funcID_normal) && gp.goid != 1 {
+       if f.valid() && showframe(f.srcFunc(), gp, false, funcID_normal) && gp.goid != 1 {
                printcreatedby1(f, pc, gp.parentGoid)
        }
 }
@@ -792,7 +786,7 @@ func printAncestorTraceback(ancestor ancestorInfo) {
        print("[originating from goroutine ", ancestor.goid, "]:\n")
        for fidx, pc := range ancestor.pcs {
                f := findfunc(pc) // f previously validated
-               if showfuncinfo(f, fidx == 0, funcID_normal, funcID_normal) {
+               if showfuncinfo(f.srcFunc(), fidx == 0, funcID_normal) {
                        printAncestorTracebackFuncInfo(f, pc)
                }
        }
@@ -801,7 +795,7 @@ func printAncestorTraceback(ancestor ancestorInfo) {
        }
        // Show what created goroutine, except main goroutine (goid 1).
        f := findfunc(ancestor.gopc)
-       if f.valid() && showfuncinfo(f, false, funcID_normal, funcID_normal) && ancestor.goid != 1 {
+       if f.valid() && showfuncinfo(f.srcFunc(), false, funcID_normal) && ancestor.goid != 1 {
                // In ancestor mode, we'll already print the goroutine ancestor.
                // Pass 0 for the goid parameter so we don't print it again.
                printcreatedby1(f, ancestor.gopc, 0)
@@ -850,35 +844,28 @@ func gcallers(gp *g, skip int, pcbuf []uintptr) int {
 
 // showframe reports whether the frame with the given characteristics should
 // be printed during a traceback.
-func showframe(f funcInfo, gp *g, firstFrame bool, funcID, childID funcID) bool {
+func showframe(sf srcFunc, gp *g, firstFrame bool, calleeID funcID) bool {
        mp := getg().m
        if mp.throwing >= throwTypeRuntime && gp != nil && (gp == mp.curg || gp == mp.caughtsig.ptr()) {
                return true
        }
-       return showfuncinfo(f, firstFrame, funcID, childID)
+       return showfuncinfo(sf, firstFrame, calleeID)
 }
 
 // showfuncinfo reports whether a function with the given characteristics should
 // be printed during a traceback.
-func showfuncinfo(f funcInfo, firstFrame bool, funcID, childID funcID) bool {
-       // Note that f may be a synthesized funcInfo for an inlined
-       // function, in which case only nameOff and funcID are set.
-
+func showfuncinfo(sf srcFunc, firstFrame bool, calleeID funcID) bool {
        level, _, _ := gotraceback()
        if level > 1 {
                // Show all frames.
                return true
        }
 
-       if !f.valid() {
-               return false
-       }
-
-       if funcID == funcID_wrapper && elideWrapperCalling(childID) {
+       if sf.funcID == funcID_wrapper && elideWrapperCalling(calleeID) {
                return false
        }
 
-       name := funcname(f)
+       name := sf.name()
 
        // Special case: always show runtime.gopanic frame
        // in the middle of a stack trace, so that we can