@@ -591,27 +591,64 @@ func (u *unwinder) cgoCallers(pcBuf []uintptr) int {
591
591
return len (pcBuf )
592
592
}
593
593
594
- // Generic traceback. Handles runtime stack prints (pcbuf == nil),
595
- // and the runtime.Callers function (pcbuf != nil).
596
- // A little clunky to merge these, but avoids
597
- // duplicating the code and all its subtlety.
594
+ // tracebackPCs populates pcBuf with the return addresses for each frame from u
595
+ // and returns the number of PCs written to pcBuf. The returned PCs correspond
596
+ // to "logical frames" rather than "physical frames"; that is if A is inlined
597
+ // into B, this will still return a PCs for both A and B. This also includes PCs
598
+ // generated by the cgo unwinder, if one is registered.
599
+ //
600
+ // If skip != 0, this skips this many logical frames.
601
+ //
602
+ // Callers should set the unwindSilentErrors flag on u.
603
+ func tracebackPCs (u * unwinder , skip int , pcBuf []uintptr ) int {
604
+ var cgoBuf [32 ]uintptr
605
+ n := 0
606
+ for ; n < len (pcBuf ) && u .valid (); u .next () {
607
+ f := u .frame .fn
608
+ cgoN := u .cgoCallers (cgoBuf [:])
609
+
610
+ // TODO: Why does &u.cache cause u to escape?
611
+ for iu , uf := newInlineUnwinder (f , u .symPC (), noEscapePtr (& u .cache )); n < len (pcBuf ) && uf .valid (); uf = iu .next (uf ) {
612
+ sf := iu .srcFunc (uf )
613
+ if sf .funcID == funcID_wrapper && elideWrapperCalling (u .calleeFuncID ) {
614
+ // ignore wrappers
615
+ } else if skip > 0 {
616
+ skip --
617
+ } else {
618
+ // Callers expect the pc buffer to contain return addresses
619
+ // and do the -1 themselves, so we add 1 to the call PC to
620
+ // create a return PC.
621
+ pcBuf [n ] = uf .pc + 1
622
+ n ++
623
+ }
624
+ u .calleeFuncID = sf .funcID
625
+ }
626
+ // Add cgo frames (if we're done skipping over the requested number of
627
+ // Go frames).
628
+ if skip == 0 {
629
+ n += copy (pcBuf [n :], cgoBuf [:cgoN ])
630
+ }
631
+ }
632
+ return n
633
+ }
634
+
635
+ // Generic traceback. Handles runtime stack prints (pcbuf == nil).
598
636
//
599
637
// The skip argument is only valid with pcbuf != nil and counts the number
600
638
// of logical frames to skip rather than physical frames (with inlining, a
601
639
// PC in pcbuf can represent multiple calls).
602
640
func gentraceback (pc0 , sp0 , lr0 uintptr , gp * g , skip int , pcbuf * uintptr , max int , callback func (* stkframe , unsafe.Pointer ) bool , v unsafe.Pointer , flags uint ) int {
641
+ if pcbuf != nil {
642
+ throw ("pcbuf argument no longer supported" )
643
+ }
603
644
if callback != nil {
604
645
throw ("callback argument no longer supported" )
605
646
}
606
647
607
648
// Translate flags
608
649
var uflags unwindFlags
609
- printing := pcbuf == nil && callback == nil
610
- if printing {
611
- uflags |= unwindPrintErrors
612
- } else {
613
- uflags |= unwindSilentErrors
614
- }
650
+ printing := true
651
+ uflags |= unwindPrintErrors
615
652
if flags & _TraceTrap != 0 {
616
653
uflags |= unwindTrap
617
654
}
@@ -634,33 +671,6 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
634
671
635
672
cgoN := u .cgoCallers (cgoBuf [:])
636
673
637
- if pcbuf != nil {
638
- // TODO: Why does cache escape? (Same below)
639
- for iu , uf := newInlineUnwinder (f , u .symPC (), noEscapePtr (& u .cache )); uf .valid (); uf = iu .next (uf ) {
640
- sf := iu .srcFunc (uf )
641
- if sf .funcID == funcID_wrapper && elideWrapperCalling (u .calleeFuncID ) {
642
- // ignore wrappers
643
- } else if skip > 0 {
644
- skip --
645
- } else if n < max {
646
- // Callers expect the pc buffer to contain return addresses
647
- // and do the -1 themselves, so we add 1 to the call PC to
648
- // create a return PC.
649
- (* [1 << 20 ]uintptr )(unsafe .Pointer (pcbuf ))[n ] = uf .pc + 1
650
- n ++
651
- }
652
- u .calleeFuncID = sf .funcID
653
- }
654
- // Add cgo frames
655
- if skip == 0 { // skip only applies to Go frames
656
- for i := 0 ; i < cgoN && n < max ; i ++ {
657
- (* [1 << 20 ]uintptr )(unsafe .Pointer (pcbuf ))[n ] = cgoBuf [i ]
658
- n ++
659
- }
660
- }
661
- n -- // offset n++ below
662
- }
663
-
664
674
if printing {
665
675
// assume skip=0 for printing.
666
676
//
@@ -981,13 +991,17 @@ func callers(skip int, pcbuf []uintptr) int {
981
991
gp := getg ()
982
992
var n int
983
993
systemstack (func () {
984
- n = gentraceback (pc , sp , 0 , gp , skip , & pcbuf [0 ], len (pcbuf ), nil , nil , 0 )
994
+ var u unwinder
995
+ u .initAt (pc , sp , 0 , gp , unwindSilentErrors )
996
+ n = tracebackPCs (& u , skip , pcbuf )
985
997
})
986
998
return n
987
999
}
988
1000
989
1001
func gcallers (gp * g , skip int , pcbuf []uintptr ) int {
990
- return gentraceback (^ uintptr (0 ), ^ uintptr (0 ), 0 , gp , skip , & pcbuf [0 ], len (pcbuf ), nil , nil , 0 )
1002
+ var u unwinder
1003
+ u .init (gp , unwindSilentErrors )
1004
+ return tracebackPCs (& u , skip , pcbuf )
991
1005
}
992
1006
993
1007
// showframe reports whether the frame with the given characteristics should
0 commit comments