]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: eliminate waspanic from gentraceback
authorAustin Clements <austin@google.com>
Sun, 17 Jul 2022 19:43:01 +0000 (15:43 -0400)
committerAustin Clements <austin@google.com>
Fri, 10 Mar 2023 17:18:23 +0000 (17:18 +0000)
gentraceback also tracks the funcID of the callee, which is more
general. Fix this up to happen in all cases and eliminate waspanic in
favor of checking the funcID of the caller.

For #54466.

Change-Id: Idc98365a6f05022db18ddcd5b3ed8684a6872a88
Reviewed-on: https://go-review.googlesource.com/c/go/+/458216
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Felix Geisendörfer <felix.geisendoerfer@datadoghq.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/runtime/traceback.go

index 507f36603703b160f261f0c3c52fbd1f25e2a94e..b3c1404b8fbfd9268f501d2b56b2b11a1913b3e7 100644 (file)
@@ -76,7 +76,6 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
        if usesLR {
                frame.lr = lr0
        }
-       waspanic := false
        cgoCtxt := gp.cgoCtxt
        printing := pcbuf == nil && callback == nil
 
@@ -121,7 +120,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
 
        var cache pcvalueCache
 
-       lastFuncID := funcID_normal
+       calleeFuncID := funcID_normal
        n := 0
        for n < max {
                // Typically:
@@ -308,7 +307,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                // deferproc a second time (if the corresponding deferred func recovers).
                // In the latter case, use a deferreturn call site as the continuation pc.
                frame.continpc = frame.pc
-               if waspanic {
+               if calleeFuncID == funcID_sigpanic {
                        if frame.fn.deferreturn != 0 {
                                frame.continpc = frame.fn.entry() + uintptr(frame.fn.deferreturn) + 1
                                // Note: this may perhaps keep return variables alive longer than
@@ -346,7 +345,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                        // See issue 34123.
                        // The pc can be at function entry when the frame is initialized without
                        // actually running code, like runtime.mstart.
-                       if (n == 0 && flags&_TraceTrap != 0) || waspanic || pc == f.entry() {
+                       if (n == 0 && flags&_TraceTrap != 0) || calleeFuncID == funcID_sigpanic || pc == f.entry() {
                                pc++
                        } else {
                                tracepc--
@@ -360,7 +359,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                                        if ix < 0 {
                                                break
                                        }
-                                       if inltree[ix].funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
+                                       if inltree[ix].funcID == funcID_wrapper && elideWrapperCalling(calleeFuncID) {
                                                // ignore wrappers
                                        } else if skip > 0 {
                                                skip--
@@ -368,14 +367,14 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                                                (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc
                                                n++
                                        }
-                                       lastFuncID = inltree[ix].funcID
+                                       calleeFuncID = inltree[ix].funcID
                                        // Back up to an instruction in the "caller".
                                        tracepc = frame.fn.entry() + uintptr(inltree[ix].parentPc)
                                        pc = tracepc + 1
                                }
                        }
                        // Record the main frame.
-                       if f.funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
+                       if f.funcID == funcID_wrapper && elideWrapperCalling(calleeFuncID) {
                                // Ignore wrapper functions (except when they trigger panics).
                        } else if skip > 0 {
                                skip--
@@ -383,7 +382,6 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                                (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc
                                n++
                        }
-                       lastFuncID = f.funcID
                        n-- // offset n++ below
                }
 
@@ -397,7 +395,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
 
                        // backup to CALL instruction to read inlining info (same logic as below)
                        tracepc := frame.pc
-                       if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry() && !waspanic {
+                       if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry() && calleeFuncID != funcID_sigpanic {
                                tracepc--
                        }
                        // If there is inlining info, print the inner frames.
@@ -417,19 +415,19 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                                        inlFunc.funcID = inltree[ix].funcID
                                        inlFunc.startLine = inltree[ix].startLine
 
-                                       if (flags&_TraceRuntimeFrames) != 0 || showframe(inlFuncInfo, gp, nprint == 0, inlFuncInfo.funcID, lastFuncID) {
+                                       if (flags&_TraceRuntimeFrames) != 0 || showframe(inlFuncInfo, gp, nprint == 0, inlFuncInfo.funcID, calleeFuncID) {
                                                name := funcname(inlFuncInfo)
                                                file, line := funcline(f, tracepc)
                                                print(name, "(...)\n")
                                                print("\t", file, ":", line, "\n")
                                                nprint++
                                        }
-                                       lastFuncID = inltree[ix].funcID
+                                       calleeFuncID = inltree[ix].funcID
                                        // Back up to an instruction in the "caller".
                                        tracepc = frame.fn.entry() + uintptr(inltree[ix].parentPc)
                                }
                        }
-                       if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, f.funcID, lastFuncID) {
+                       if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, f.funcID, calleeFuncID) {
                                // Print during crash.
                                //      main(0x1, 0x2, 0x3)
                                //              /home/rsc/go/src/runtime/x.go:23 +0xf
@@ -453,7 +451,6 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                                print("\n")
                                nprint++
                        }
-                       lastFuncID = f.funcID
                }
                n++
 
@@ -469,8 +466,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                        }
                }
 
-               waspanic = f.funcID == funcID_sigpanic
-               injectedCall := waspanic || f.funcID == funcID_asyncPreempt || f.funcID == funcID_debugCallV2
+               injectedCall := f.funcID == funcID_sigpanic || f.funcID == funcID_asyncPreempt || f.funcID == funcID_debugCallV2
 
                // Do not unwind past the bottom of the stack.
                if !flr.valid() {
@@ -485,6 +481,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
                }
 
                // Unwind to next frame.
+               calleeFuncID = f.funcID
                frame.fn = flr
                frame.pc = frame.lr
                frame.lr = 0