diff options
| author | Austin Clements <austin@google.com> | 2023-02-05 22:02:03 -0500 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2023-03-10 17:18:29 +0000 |
| commit | d829b626812cfe9ee53cb71ccdd75d3fa0eda265 (patch) | |
| tree | 672ad19b188ae2efc770c5521271bba0ffdaf1ea /src | |
| parent | f52bede354102a5e16e19381b93d4a469d1286d4 (diff) | |
| download | go-d829b626812cfe9ee53cb71ccdd75d3fa0eda265.tar.xz | |
runtime: use srcFunc for showframe
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>
Diffstat (limited to 'src')
| -rw-r--r-- | src/runtime/traceback.go | 37 |
1 files changed, 12 insertions, 25 deletions
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index d04bbf2d57..e873ac74be 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -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 |
