@@ -569,6 +569,28 @@ func (u *unwinder) symPC() uintptr {
569
569
return u .frame .pc
570
570
}
571
571
572
+ // cgoCallers populates pcBuf with the cgo callers of the current frame using
573
+ // the registered cgo unwinder. It returns the number of PCs written to pcBuf.
574
+ // If the current frame is not a cgo frame or if there's no registered cgo
575
+ // unwinder, it returns 0.
576
+ func (u * unwinder ) cgoCallers (pcBuf []uintptr ) int {
577
+ if cgoTraceback == nil || u .frame .fn .funcID != funcID_cgocallback || u .cgoCtxt < 0 {
578
+ // We don't have a cgo unwinder (typical case), or we do but we're not
579
+ // in a cgo frame or we're out of cgo context.
580
+ return 0
581
+ }
582
+
583
+ ctxt := u .g .ptr ().cgoCtxt [u .cgoCtxt ]
584
+ u .cgoCtxt --
585
+ cgoContextPCs (ctxt , pcBuf )
586
+ for i , pc := range pcBuf {
587
+ if pc == 0 {
588
+ return i
589
+ }
590
+ }
591
+ return len (pcBuf )
592
+ }
593
+
572
594
// Generic traceback. Handles runtime stack prints (pcbuf == nil),
573
595
// and the runtime.Callers function (pcbuf != nil).
574
596
// A little clunky to merge these, but avoids
@@ -605,10 +627,13 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
605
627
606
628
nprint := 0
607
629
n := 0
630
+ var cgoBuf [32 ]uintptr
608
631
for ; n < max && u .valid (); u .next () {
609
632
frame := & u .frame
610
633
f := frame .fn
611
634
635
+ cgoN := u .cgoCallers (cgoBuf [:])
636
+
612
637
if pcbuf != nil {
613
638
// TODO: Why does cache escape? (Same below)
614
639
for iu , uf := newInlineUnwinder (f , u .symPC (), noEscapePtr (& u .cache )); uf .valid (); uf = iu .next (uf ) {
@@ -626,6 +651,13 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
626
651
}
627
652
u .calleeFuncID = sf .funcID
628
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
+ }
629
661
n -- // offset n++ below
630
662
}
631
663
@@ -669,18 +701,31 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
669
701
nprint ++
670
702
}
671
703
}
672
- }
673
- n ++
674
-
675
- if f .funcID == funcID_cgocallback && u .cgoCtxt >= 0 {
676
- ctxt := gp .cgoCtxt [u .cgoCtxt ]
677
- u .cgoCtxt --
678
-
679
- // skip only applies to Go frames.
680
- if skip == 0 {
681
- n = tracebackCgoContext (pcbuf , printing , ctxt , n , max )
704
+ // Print cgo frames.
705
+ if cgoN > 0 {
706
+ var arg cgoSymbolizerArg
707
+ anySymbolized := false
708
+ for _ , pc := range cgoBuf [:cgoN ] {
709
+ if n >= max {
710
+ break
711
+ }
712
+ if cgoSymbolizer == nil {
713
+ print ("non-Go function at pc=" , hex (pc ), "\n " )
714
+ } else {
715
+ c := printOneCgoTraceback (pc , max - n , & arg )
716
+ n += c - 1 // +1 a few lines down
717
+ anySymbolized = true
718
+ }
719
+ nprint ++
720
+ }
721
+ if anySymbolized {
722
+ // Free symbolization state.
723
+ arg .pc = 0
724
+ callCgoSymbolizer (& arg )
725
+ }
682
726
}
683
727
}
728
+ n ++
684
729
}
685
730
686
731
if printing {
@@ -791,39 +836,6 @@ printloop:
791
836
}
792
837
}
793
838
794
- // tracebackCgoContext handles tracing back a cgo context value, from
795
- // the context argument to setCgoTraceback, for the gentraceback
796
- // function. It returns the new value of n.
797
- func tracebackCgoContext (pcbuf * uintptr , printing bool , ctxt uintptr , n , max int ) int {
798
- var cgoPCs [32 ]uintptr
799
- cgoContextPCs (ctxt , cgoPCs [:])
800
- var arg cgoSymbolizerArg
801
- anySymbolized := false
802
- for _ , pc := range cgoPCs {
803
- if pc == 0 || n >= max {
804
- break
805
- }
806
- if pcbuf != nil {
807
- (* [1 << 20 ]uintptr )(unsafe .Pointer (pcbuf ))[n ] = pc
808
- }
809
- if printing {
810
- if cgoSymbolizer == nil {
811
- print ("non-Go function at pc=" , hex (pc ), "\n " )
812
- } else {
813
- c := printOneCgoTraceback (pc , max - n , & arg )
814
- n += c - 1 // +1 a few lines down
815
- anySymbolized = true
816
- }
817
- }
818
- n ++
819
- }
820
- if anySymbolized {
821
- arg .pc = 0
822
- callCgoSymbolizer (& arg )
823
- }
824
- return n
825
- }
826
-
827
839
func printcreatedby (gp * g ) {
828
840
// Show what created goroutine, except main goroutine (goid 1).
829
841
pc := gp .gopc
0 commit comments