1
2
3
4
5 package main
6
7
8
9
10
21 import "C"
22
23 import (
24 "fmt"
25 "runtime"
26 "sync"
27 "unsafe"
28 )
29
30 func init() {
31 register("TracebackContext", TracebackContext)
32 register("TracebackContextPreemption", TracebackContextPreemption)
33 }
34
35 var tracebackOK bool
36
37 func TracebackContext() {
38 runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContext), unsafe.Pointer(C.tcSymbolizer))
39 C.C1()
40 if got := C.getContextCount(); got != 0 {
41 fmt.Printf("at end contextCount == %d, expected 0\n", got)
42 tracebackOK = false
43 }
44 if tracebackOK {
45 fmt.Println("OK")
46 }
47 }
48
49
50 func G1() {
51 C.C2()
52 }
53
54
55 func G2() {
56 pc := make([]uintptr, 32)
57 n := runtime.Callers(0, pc)
58 cf := runtime.CallersFrames(pc[:n])
59 var frames []runtime.Frame
60 for {
61 frame, more := cf.Next()
62 frames = append(frames, frame)
63 if !more {
64 break
65 }
66 }
67
68 want := []struct {
69 function string
70 line int
71 }{
72 {"main.G2", 0},
73 {"cFunction", 0x10200},
74 {"cFunction", 0x200},
75 {"cFunction", 0x10201},
76 {"cFunction", 0x201},
77 {"main.G1", 0},
78 {"cFunction", 0x10100},
79 {"cFunction", 0x100},
80 {"main.TracebackContext", 0},
81 }
82
83 ok := true
84 i := 0
85 wantLoop:
86 for _, w := range want {
87 for ; i < len(frames); i++ {
88 if w.function == frames[i].Function {
89 if w.line != 0 && w.line != frames[i].Line {
90 fmt.Printf("found function %s at wrong line %#x (expected %#x)\n", w.function, frames[i].Line, w.line)
91 ok = false
92 }
93 i++
94 continue wantLoop
95 }
96 }
97 fmt.Printf("did not find function %s in\n", w.function)
98 for _, f := range frames {
99 fmt.Println(f)
100 }
101 ok = false
102 break
103 }
104 tracebackOK = ok
105 if got := C.getContextCount(); got != 2 {
106 fmt.Printf("at bottom contextCount == %d, expected 2\n", got)
107 tracebackOK = false
108 }
109 }
110
111
112 func TracebackContextPreemption() {
113 runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContextSimple), unsafe.Pointer(C.tcSymbolizer))
114
115 const funcs = 10
116 const calls = 1e5
117 var wg sync.WaitGroup
118 for i := 0; i < funcs; i++ {
119 wg.Add(1)
120 go func(i int) {
121 defer wg.Done()
122 for j := 0; j < calls; j++ {
123 C.TracebackContextPreemptionCallGo(C.int(i*calls + j))
124 }
125 }(i)
126 }
127 wg.Wait()
128
129 fmt.Println("OK")
130 }
131
132
133 func TracebackContextPreemptionGoFunction(i C.int) {
134
135 fmt.Sprintf("%d\n", i)
136 }
137
View as plain text