@@ -146,7 +146,6 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
146
146
cgoCtxt := gp .cgoCtxt
147
147
printing := pcbuf == nil && callback == nil
148
148
_defer := gp ._defer
149
- elideWrapper := false
150
149
151
150
for _defer != nil && _defer .sp == _NoArgs {
152
151
_defer = _defer .link
@@ -392,32 +391,39 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
392
391
// any frames. And don't elide wrappers that
393
392
// called panic rather than the wrapped
394
393
// 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 {
410
404
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 ) {
412
409
name := funcnameFromNameoff (f , inltree [ix ].func_ )
410
+ file , line := funcline (f , tracepc )
413
411
print (name , "(...)\n " )
414
412
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 ++
419
414
}
415
+ lastFuncID = inltree [ix ].funcID
416
+ // Back up to an instruction in the "caller".
417
+ tracepc = frame .fn .entry + uintptr (inltree [ix ].parentPc )
420
418
}
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 )
421
427
if name == "runtime.gopanic" {
422
428
name = "panic"
423
429
}
@@ -444,7 +450,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
444
450
print ("\n " )
445
451
nprint ++
446
452
}
447
- elideWrapper = nextElideWrapper
453
+ lastFuncID = f . funcID
448
454
}
449
455
n ++
450
456
@@ -669,7 +675,7 @@ func printcreatedby(gp *g) {
669
675
// Show what created goroutine, except main goroutine (goid 1).
670
676
pc := gp .gopc
671
677
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 {
673
679
printcreatedby1 (f , pc )
674
680
}
675
681
}
@@ -756,19 +762,18 @@ func traceback1(pc, sp, lr uintptr, gp *g, flags uint) {
756
762
// TODO: Unify this with gentraceback and CallersFrames.
757
763
func printAncestorTraceback (ancestor ancestorInfo ) {
758
764
print ("[originating from goroutine " , ancestor .goid , "]:\n " )
759
- elideWrapper := false
760
765
for fidx , pc := range ancestor .pcs {
761
766
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 )
764
769
}
765
770
}
766
771
if len (ancestor .pcs ) == _TracebackMaxFrames {
767
772
print ("...additional frames elided...\n " )
768
773
}
769
774
// Show what created goroutine, except main goroutine (goid 1).
770
775
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 {
772
777
printcreatedby1 (f , ancestor .gopc )
773
778
}
774
779
}
@@ -777,27 +782,16 @@ func printAncestorTraceback(ancestor ancestorInfo) {
777
782
// within an ancestor traceback. The precision of this info is reduced
778
783
// due to only have access to the pcs at the time of the caller
779
784
// 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 {
788
788
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_ )
798
792
}
799
793
}
800
- name := funcname ( f )
794
+ file , line := funcline ( f , pc )
801
795
if name == "runtime.gopanic" {
802
796
name = "panic"
803
797
}
@@ -807,7 +801,6 @@ func printAncestorTracebackFuncInfo(f funcInfo, pc uintptr) bool {
807
801
print (" +" , hex (pc - f .entry ))
808
802
}
809
803
print ("\n " )
810
- return elideWrapperCalling (f .funcID )
811
804
}
812
805
813
806
func callers (skip int , pcbuf []uintptr ) int {
@@ -825,15 +818,19 @@ func gcallers(gp *g, skip int, pcbuf []uintptr) int {
825
818
return gentraceback (^ uintptr (0 ), ^ uintptr (0 ), 0 , gp , skip , & pcbuf [0 ], len (pcbuf ), nil , nil , 0 )
826
819
}
827
820
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 {
829
824
g := getg ()
830
825
if g .m .throwing > 0 && gp != nil && (gp == g .m .curg || gp == g .m .caughtsig .ptr ()) {
831
826
return true
832
827
}
833
- return showfuncinfo (f , firstFrame , elideWrapper )
828
+ return showfuncinfo (f , firstFrame , funcID , childID )
834
829
}
835
830
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 {
837
834
level , _ , _ := gotraceback ()
838
835
if level > 1 {
839
836
// Show all frames.
@@ -844,11 +841,8 @@ func showfuncinfo(f funcInfo, firstFrame, elideWrapper bool) bool {
844
841
return false
845
842
}
846
843
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
852
846
}
853
847
854
848
name := funcname (f )
0 commit comments