LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "arch_GOARCH.h" | 6 #include "arch_GOARCH.h" |
7 #include "malloc.h" | 7 #include "malloc.h" |
8 | 8 |
9 void runtime·deferproc(void); | 9 void runtime·deferproc(void); |
10 void runtime·newproc(void); | 10 void runtime·newproc(void); |
11 void runtime·newstack(void); | 11 void runtime·newstack(void); |
12 void runtime·morestack(void); | 12 void runtime·morestack(void); |
13 void runtime·sigpanic(void); | 13 void runtime·sigpanic(void); |
14 void _div(void); | 14 void _div(void); |
15 void _mod(void); | 15 void _mod(void); |
16 void _divu(void); | 16 void _divu(void); |
17 void _modu(void); | 17 void _modu(void); |
18 | 18 |
19 int32 | 19 int32 |
20 runtime·gentraceback(byte *pc0, byte *sp, byte *lr0, G *gp, int32 skip, uintptr
*pcbuf, int32 max) | 20 runtime·gentraceback(byte *pc0, byte *sp, byte *lr0, G *gp, int32 skip, uintptr
*pcbuf, int32 max) |
21 { | 21 { |
22 int32 i, n, iter; | 22 int32 i, n, iter; |
23 uintptr pc, lr, tracepc, x; | 23 uintptr pc, lr, tracepc, x; |
24 byte *fp, *p; | 24 byte *fp, *p; |
25 bool waspanic; | 25 bool waspanic; |
26 Stktop *stk; | 26 Stktop *stk; |
27 Func *f; | 27 Func *f; |
28 » | 28 |
29 pc = (uintptr)pc0; | 29 pc = (uintptr)pc0; |
30 lr = (uintptr)lr0; | 30 lr = (uintptr)lr0; |
31 fp = nil; | 31 fp = nil; |
32 waspanic = false; | 32 waspanic = false; |
33 | 33 |
34 // If the PC is goexit, the goroutine hasn't started yet. | 34 // If the PC is goexit, the goroutine hasn't started yet. |
35 if(pc == (uintptr)runtime·goexit) { | 35 if(pc == (uintptr)runtime·goexit) { |
36 pc = (uintptr)gp->entry; | 36 pc = (uintptr)gp->entry; |
37 lr = (uintptr)runtime·goexit; | 37 lr = (uintptr)runtime·goexit; |
38 } | 38 } |
(...skipping 14 matching lines...) Expand all Loading... |
53 // fp is the frame pointer (caller's stack pointer) at that
program counter, or nil if unknown. | 53 // fp is the frame pointer (caller's stack pointer) at that
program counter, or nil if unknown. |
54 // stk is the stack containing sp. | 54 // stk is the stack containing sp. |
55 // The caller's program counter is lr, unless lr is zero, i
n which case it is *(uintptr*)sp. | 55 // The caller's program counter is lr, unless lr is zero, i
n which case it is *(uintptr*)sp. |
56 ················ | 56 ················ |
57 if(pc == (uintptr)runtime·lessstack) { | 57 if(pc == (uintptr)runtime·lessstack) { |
58 // Hit top of stack segment. Unwind to next segment. | 58 // Hit top of stack segment. Unwind to next segment. |
59 pc = (uintptr)stk->gobuf.pc; | 59 pc = (uintptr)stk->gobuf.pc; |
60 sp = (byte*)stk->gobuf.sp; | 60 sp = (byte*)stk->gobuf.sp; |
61 lr = 0; | 61 lr = 0; |
62 fp = nil; | 62 fp = nil; |
63 » » » if(pcbuf == nil) | 63 » » » if(pcbuf == nil && runtime·showframe(nil, gp == m->curg)
) |
64 runtime·printf("----- stack segment boundary ---
--\n"); | 64 runtime·printf("----- stack segment boundary ---
--\n"); |
65 stk = (Stktop*)stk->stackbase; | 65 stk = (Stktop*)stk->stackbase; |
66 continue; | 66 continue; |
67 } | 67 } |
68 ················ | 68 ················ |
69 if(pc <= 0x1000 || (f = runtime·findfunc(pc)) == nil) { | 69 if(pc <= 0x1000 || (f = runtime·findfunc(pc)) == nil) { |
70 // Dangerous, but worthwhile: see if this is a closure b
y | 70 // Dangerous, but worthwhile: see if this is a closure b
y |
71 // decoding the instruction stream. | 71 // decoding the instruction stream. |
72 // | 72 // |
73 // We check p < p+4 to avoid wrapping and faulting if | 73 // We check p < p+4 to avoid wrapping and faulting if |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 fp = sp; | 111 fp = sp; |
112 if(pc > f->entry && f->frame >= 0) | 112 if(pc > f->entry && f->frame >= 0) |
113 fp += f->frame; | 113 fp += f->frame; |
114 } | 114 } |
115 | 115 |
116 if(skip > 0) | 116 if(skip > 0) |
117 skip--; | 117 skip--; |
118 else if(pcbuf != nil) | 118 else if(pcbuf != nil) |
119 pcbuf[n++] = pc; | 119 pcbuf[n++] = pc; |
120 else { | 120 else { |
121 » » » if(runtime·showframe(f)) { | 121 » » » if(runtime·showframe(f, gp == m->curg)) { |
122 // Print during crash. | 122 // Print during crash. |
123 // main(0x1, 0x2, 0x3) | 123 // main(0x1, 0x2, 0x3) |
124 // /home/rsc/go/src/runtime/x.go:23
+0xf | 124 // /home/rsc/go/src/runtime/x.go:23
+0xf |
125 tracepc = pc; // back up to CALL instruction f
or funcline. | 125 tracepc = pc; // back up to CALL instruction f
or funcline. |
126 if(n > 0 && pc > f->entry && !waspanic) | 126 if(n > 0 && pc > f->entry && !waspanic) |
127 tracepc -= sizeof(uintptr); | 127 tracepc -= sizeof(uintptr); |
128 runtime·printf("%S(", f->name); | 128 runtime·printf("%S(", f->name); |
129 for(i = 0; i < f->args; i++) { | 129 for(i = 0; i < f->args; i++) { |
130 if(i != 0) | 130 if(i != 0) |
131 runtime·prints(", "); | 131 runtime·prints(", "); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 // If this was div or divu or mod or modu, the caller had | 177 // If this was div or divu or mod or modu, the caller had |
178 // an extra 8 bytes on its stack. Adjust sp. | 178 // an extra 8 bytes on its stack. Adjust sp. |
179 if(f->entry == (uintptr)_div || f->entry == (uintptr)_divu || f-
>entry == (uintptr)_mod || f->entry == (uintptr)_modu) | 179 if(f->entry == (uintptr)_div || f->entry == (uintptr)_divu || f-
>entry == (uintptr)_mod || f->entry == (uintptr)_modu) |
180 sp += 8; | 180 sp += 8; |
181 ················ | 181 ················ |
182 // If this was deferproc or newproc, the caller had an extra 12. | 182 // If this was deferproc or newproc, the caller had an extra 12. |
183 if(f->entry == (uintptr)runtime·deferproc || f->entry == (uintpt
r)runtime·newproc) | 183 if(f->entry == (uintptr)runtime·deferproc || f->entry == (uintpt
r)runtime·newproc) |
184 sp += 12; | 184 sp += 12; |
185 } | 185 } |
186 ········ | 186 ········ |
187 » if(pcbuf == nil && (pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) !=
nil && gp->goid != 1) { | 187 » if(pcbuf == nil && (pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) !=
nil |
| 188 » » » && runtime·showframe(f, gp == m->curg) && gp->goid != 1)
{ |
188 runtime·printf("created by %S\n", f->name); | 189 runtime·printf("created by %S\n", f->name); |
189 tracepc = pc; // back up to CALL instruction for funcline. | 190 tracepc = pc; // back up to CALL instruction for funcline. |
190 if(n > 0 && pc > f->entry) | 191 if(n > 0 && pc > f->entry) |
191 tracepc -= sizeof(uintptr); | 192 tracepc -= sizeof(uintptr); |
192 runtime·printf("\t%S:%d", f->src, runtime·funcline(f, tracepc)); | 193 runtime·printf("\t%S:%d", f->src, runtime·funcline(f, tracepc)); |
193 if(pc > f->entry) | 194 if(pc > f->entry) |
194 runtime·printf(" +%p", (uintptr)(pc - f->entry)); | 195 runtime·printf(" +%p", (uintptr)(pc - f->entry)); |
195 runtime·printf("\n"); | 196 runtime·printf("\n"); |
196 } | 197 } |
197 | 198 |
(...skipping 10 matching lines...) Expand all Loading... |
208 int32 | 209 int32 |
209 runtime·callers(int32 skip, uintptr *pcbuf, int32 m) | 210 runtime·callers(int32 skip, uintptr *pcbuf, int32 m) |
210 { | 211 { |
211 byte *pc, *sp; | 212 byte *pc, *sp; |
212 ········ | 213 ········ |
213 sp = runtime·getcallersp(&skip); | 214 sp = runtime·getcallersp(&skip); |
214 pc = runtime·getcallerpc(&skip); | 215 pc = runtime·getcallerpc(&skip); |
215 | 216 |
216 return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m); | 217 return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m); |
217 } | 218 } |
LEFT | RIGHT |