@@ -146,7 +146,6 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
146146 cgoCtxt := gp .cgoCtxt
147147 printing := pcbuf == nil && callback == nil
148148 _defer := gp ._defer
149- elideWrapper := false
150149
151150 for _defer != nil && _defer .sp == _NoArgs {
152151 _defer = _defer .link
@@ -392,32 +391,39 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
392391 // any frames. And don't elide wrappers that
393392 // called panic rather than the wrapped
394393 // function. Otherwise, leave them out.
395- name := funcname (f )
396- nextElideWrapper := elideWrapperCalling (f .funcID )
397- if (flags & _TraceRuntimeFrames ) != 0 || showframe (f , gp , nprint == 0 , elideWrapper && nprint != 0 ) {
398- // Print during crash.
399- // main(0x1, 0x2, 0x3)
400- // /home/rsc/go/src/runtime/x.go:23 +0xf
401- //
402- tracepc := frame .pc // back up to CALL instruction for funcline.
403- if (n > 0 || flags & _TraceTrap == 0 ) && frame .pc > f .entry && ! waspanic {
404- tracepc --
405- }
406- file , line := funcline (f , tracepc )
407- inldata := funcdata (f , _FUNCDATA_InlTree )
408- if inldata != nil {
409- inltree := (* [1 << 20 ]inlinedCall )(inldata )
394+
395+ // backup to CALL instruction to read inlining info (same logic as below)
396+ tracepc := frame .pc
397+ if (n > 0 || flags & _TraceTrap == 0 ) && frame .pc > f .entry && ! waspanic {
398+ tracepc --
399+ }
400+ // If there is inlining info, print the inner frames.
401+ if inldata := funcdata (f , _FUNCDATA_InlTree ); inldata != nil {
402+ inltree := (* [1 << 20 ]inlinedCall )(inldata )
403+ for {
410404 ix := pcdatavalue (f , _PCDATA_InlTreeIndex , tracepc , nil )
411- for ix != - 1 {
405+ if ix < 0 {
406+ break
407+ }
408+ if (flags & _TraceRuntimeFrames ) != 0 || showframe (f , gp , nprint == 0 , inltree [ix ].funcID , lastFuncID ) {
412409 name := funcnameFromNameoff (f , inltree [ix ].func_ )
410+ file , line := funcline (f , tracepc )
413411 print (name , "(...)\n " )
414412 print ("\t " , file , ":" , line , "\n " )
415-
416- file = funcfile (f , inltree [ix ].file )
417- line = inltree [ix ].line
418- ix = int32 (inltree [ix ].parent )
413+ nprint ++
419414 }
415+ lastFuncID = inltree [ix ].funcID
416+ // Back up to an instruction in the "caller".
417+ tracepc = frame .fn .entry + uintptr (inltree [ix ].parentPc )
420418 }
419+ }
420+ if (flags & _TraceRuntimeFrames ) != 0 || showframe (f , gp , nprint == 0 , f .funcID , lastFuncID ) {
421+ // Print during crash.
422+ // main(0x1, 0x2, 0x3)
423+ // /home/rsc/go/src/runtime/x.go:23 +0xf
424+ //
425+ name := funcname (f )
426+ file , line := funcline (f , tracepc )
421427 if name == "runtime.gopanic" {
422428 name = "panic"
423429 }
@@ -444,7 +450,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
444450 print ("\n " )
445451 nprint ++
446452 }
447- elideWrapper = nextElideWrapper
453+ lastFuncID = f . funcID
448454 }
449455 n ++
450456
@@ -669,7 +675,7 @@ func printcreatedby(gp *g) {
669675 // Show what created goroutine, except main goroutine (goid 1).
670676 pc := gp .gopc
671677 f := findfunc (pc )
672- if f .valid () && showframe (f , gp , false , false ) && gp .goid != 1 {
678+ if f .valid () && showframe (f , gp , false , funcID_normal , funcID_normal ) && gp .goid != 1 {
673679 printcreatedby1 (f , pc )
674680 }
675681}
@@ -756,19 +762,18 @@ func traceback1(pc, sp, lr uintptr, gp *g, flags uint) {
756762// TODO: Unify this with gentraceback and CallersFrames.
757763func printAncestorTraceback (ancestor ancestorInfo ) {
758764 print ("[originating from goroutine " , ancestor .goid , "]:\n " )
759- elideWrapper := false
760765 for fidx , pc := range ancestor .pcs {
761766 f := findfunc (pc ) // f previously validated
762- if showfuncinfo (f , fidx == 0 , elideWrapper && fidx != 0 ) {
763- elideWrapper = printAncestorTracebackFuncInfo (f , pc )
767+ if showfuncinfo (f , fidx == 0 , funcID_normal , funcID_normal ) {
768+ printAncestorTracebackFuncInfo (f , pc )
764769 }
765770 }
766771 if len (ancestor .pcs ) == _TracebackMaxFrames {
767772 print ("...additional frames elided...\n " )
768773 }
769774 // Show what created goroutine, except main goroutine (goid 1).
770775 f := findfunc (ancestor .gopc )
771- if f .valid () && showfuncinfo (f , false , false ) && ancestor .goid != 1 {
776+ if f .valid () && showfuncinfo (f , false , funcID_normal , funcID_normal ) && ancestor .goid != 1 {
772777 printcreatedby1 (f , ancestor .gopc )
773778 }
774779}
@@ -777,27 +782,16 @@ func printAncestorTraceback(ancestor ancestorInfo) {
777782// within an ancestor traceback. The precision of this info is reduced
778783// due to only have access to the pcs at the time of the caller
779784// goroutine being created.
780- func printAncestorTracebackFuncInfo (f funcInfo , pc uintptr ) bool {
781- tracepc := pc // back up to CALL instruction for funcline.
782- if pc > f .entry {
783- tracepc -= sys .PCQuantum
784- }
785- file , line := funcline (f , tracepc )
786- inldata := funcdata (f , _FUNCDATA_InlTree )
787- if inldata != nil {
785+ func printAncestorTracebackFuncInfo (f funcInfo , pc uintptr ) {
786+ name := funcname (f )
787+ if inldata := funcdata (f , _FUNCDATA_InlTree ); inldata != nil {
788788 inltree := (* [1 << 20 ]inlinedCall )(inldata )
789- ix := pcdatavalue (f , _PCDATA_InlTreeIndex , tracepc , nil )
790- for ix != - 1 {
791- name := funcnameFromNameoff (f , inltree [ix ].func_ )
792- print (name , "(...)\n " )
793- print ("\t " , file , ":" , line , "\n " )
794-
795- file = funcfile (f , inltree [ix ].file )
796- line = inltree [ix ].line
797- ix = int32 (inltree [ix ].parent )
789+ ix := pcdatavalue (f , _PCDATA_InlTreeIndex , pc , nil )
790+ if ix >= 0 {
791+ name = funcnameFromNameoff (f , inltree [ix ].func_ )
798792 }
799793 }
800- name := funcname ( f )
794+ file , line := funcline ( f , pc )
801795 if name == "runtime.gopanic" {
802796 name = "panic"
803797 }
@@ -807,7 +801,6 @@ func printAncestorTracebackFuncInfo(f funcInfo, pc uintptr) bool {
807801 print (" +" , hex (pc - f .entry ))
808802 }
809803 print ("\n " )
810- return elideWrapperCalling (f .funcID )
811804}
812805
813806func callers (skip int , pcbuf []uintptr ) int {
@@ -825,15 +818,19 @@ func gcallers(gp *g, skip int, pcbuf []uintptr) int {
825818 return gentraceback (^ uintptr (0 ), ^ uintptr (0 ), 0 , gp , skip , & pcbuf [0 ], len (pcbuf ), nil , nil , 0 )
826819}
827820
828- func showframe (f funcInfo , gp * g , firstFrame , elideWrapper bool ) bool {
821+ // showframe reports whether the frame with the given characteristics should
822+ // be printed during a traceback.
823+ func showframe (f funcInfo , gp * g , firstFrame bool , funcID , childID funcID ) bool {
829824 g := getg ()
830825 if g .m .throwing > 0 && gp != nil && (gp == g .m .curg || gp == g .m .caughtsig .ptr ()) {
831826 return true
832827 }
833- return showfuncinfo (f , firstFrame , elideWrapper )
828+ return showfuncinfo (f , firstFrame , funcID , childID )
834829}
835830
836- func showfuncinfo (f funcInfo , firstFrame , elideWrapper bool ) bool {
831+ // showfuncinfo reports whether a function with the given characteristics should
832+ // be printed during a traceback.
833+ func showfuncinfo (f funcInfo , firstFrame bool , funcID , childID funcID ) bool {
837834 level , _ , _ := gotraceback ()
838835 if level > 1 {
839836 // Show all frames.
@@ -844,11 +841,8 @@ func showfuncinfo(f funcInfo, firstFrame, elideWrapper bool) bool {
844841 return false
845842 }
846843
847- if elideWrapper {
848- file , _ := funcline (f , f .entry )
849- if file == "<autogenerated>" {
850- return false
851- }
844+ if funcID == funcID_wrapper && elideWrapperCalling (childID ) {
845+ return false
852846 }
853847
854848 name := funcname (f )
0 commit comments