From: Austin Clements Date: Sun, 17 Jul 2022 19:43:01 +0000 (-0400) Subject: runtime: eliminate waspanic from gentraceback X-Git-Tag: go1.21rc1~1329 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5acd2d658ee87e5b4d73ff815e5ed41d4e4b77f3;p=gostls13.git runtime: eliminate waspanic from gentraceback 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 Reviewed-by: Felix Geisendörfer Reviewed-by: Michael Knyszek Reviewed-by: Michael Pratt TryBot-Result: Gopher Robot --- diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index 507f366037..b3c1404b8f 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -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