LEFT | RIGHT |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 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 "defs_GOOS_GOARCH.h" | 6 #include "defs_GOOS_GOARCH.h" |
7 #include "os_GOOS.h" | 7 #include "os_GOOS.h" |
8 #include "arch_GOARCH.h" | |
9 #include "signals_GOOS.h" | 8 #include "signals_GOOS.h" |
10 | 9 |
11 void | 10 void |
12 runtime·dumpregs(Ureg *u) | 11 runtime·dumpregs(Ureg *u) |
13 { | 12 { |
14 » runtime·printf("ax %X\n", u->ax); | 13 » runtime·printf("ax» %X\n", u->ax); |
15 » runtime·printf("bx %X\n", u->bx); | 14 » runtime·printf("bx» %X\n", u->bx); |
16 » runtime·printf("cx %X\n", u->cx); | 15 » runtime·printf("cx» %X\n", u->cx); |
17 » runtime·printf("dx %X\n", u->dx); | 16 » runtime·printf("dx» %X\n", u->dx); |
18 » runtime·printf("di %X\n", u->di); | 17 » runtime·printf("di» %X\n", u->di); |
19 » runtime·printf("si %X\n", u->si); | 18 » runtime·printf("si» %X\n", u->si); |
20 » runtime·printf("bp %X\n", u->bp); | 19 » runtime·printf("bp» %X\n", u->bp); |
21 » runtime·printf("sp %X\n", u->sp); | 20 » runtime·printf("sp» %X\n", u->sp); |
22 » runtime·printf("r8 %X\n", u->r8); | 21 » runtime·printf("r8» %X\n", u->r8); |
23 » runtime·printf("r9 %X\n", u->r9); | 22 » runtime·printf("r9» %X\n", u->r9); |
24 » runtime·printf("r10 %X\n", u->r10); | 23 » runtime·printf("r10» %X\n", u->r10); |
25 » runtime·printf("r11 %X\n", u->r11); | 24 » runtime·printf("r11» %X\n", u->r11); |
26 » runtime·printf("r12 %X\n", u->r12); | 25 » runtime·printf("r12» %X\n", u->r12); |
27 » runtime·printf("r13 %X\n", u->r13); | 26 » runtime·printf("r13» %X\n", u->r13); |
28 » runtime·printf("r14 %X\n", u->r14); | 27 » runtime·printf("r14» %X\n", u->r14); |
29 » runtime·printf("r15 %X\n", u->r15); | 28 » runtime·printf("r15» %X\n", u->r15); |
30 » runtime·printf("ip %X\n", u->ip); | 29 » runtime·printf("ip» %X\n", u->ip); |
31 » runtime·printf("flags %X\n", u->flags); | 30 » runtime·printf("flags» %X\n", u->flags); |
32 » runtime·printf("cs %X\n", (uint64)u->cs); | 31 » runtime·printf("cs» %X\n", (uint64)u->cs); |
33 » runtime·printf("fs %X\n", (uint64)u->fs); | 32 » runtime·printf("fs» %X\n", (uint64)u->fs); |
34 » runtime·printf("gs %X\n", (uint64)u->gs); | 33 » runtime·printf("gs» %X\n", (uint64)u->gs); |
35 } | 34 } |
36 | 35 |
37 int32 | 36 int32 |
38 runtime·sighandler(void *v, int8 *s, G *gp) | 37 runtime·sighandler(void *v, int8 *s, G *gp) |
39 { | 38 { |
40 Ureg *ureg; | 39 Ureg *ureg; |
| 40 uintptr *sp; |
41 SigTab *sig, *nsig; | 41 SigTab *sig, *nsig; |
42 » int32 l, i; | 42 » int32 len, i; |
43 | 43 |
44 if(!s) | 44 if(!s) |
45 return NCONT; | 45 return NCONT; |
46 | |
47 if(s && *s == 0) | |
48 runtime·exits(nil); | |
49 ························ | 46 ························ |
50 » l = runtime·findnull((byte*)s); | 47 » len = runtime·findnull((byte*)s); |
51 » if(l <= 4 || runtime·mcmp((byte*)s, (byte*)"sys:", 4) != 0) | 48 » if(len <= 4 || runtime·mcmp((byte*)s, (byte*)"sys:", 4) != 0) |
52 » » runtime·exits(s); | 49 » » return NDFLT; |
53 | 50 |
54 nsig = nil; | 51 nsig = nil; |
55 sig = runtime·sigtab; | 52 sig = runtime·sigtab; |
56 for(i=0; i < NSIG; i++) { | 53 for(i=0; i < NSIG; i++) { |
57 if(runtime·strstr((byte*)s, (byte*)sig->name)) { | 54 if(runtime·strstr((byte*)s, (byte*)sig->name)) { |
58 nsig = sig; | 55 nsig = sig; |
59 break; | 56 break; |
60 } | 57 } |
61 sig++; | 58 sig++; |
62 } | 59 } |
63 | 60 |
64 if(nsig == nil) | 61 if(nsig == nil) |
65 » » runtime·exits(s); | 62 » » return NDFLT; |
66 | 63 |
67 ureg = v; | 64 ureg = v; |
68 if(nsig->flags & SigPanic) { | 65 if(nsig->flags & SigPanic) { |
69 » » if(gp == nil) | 66 » » if(gp == nil || m->notesig == 0) |
70 goto Throw; | 67 goto Throw; |
| 68 |
| 69 // Save error string from sigtramp's stack, |
| 70 // into gsignal->sigcode0, so we can reliably |
| 71 // access it from the panic routines. |
| 72 if(len > ERRMAX) |
| 73 len = ERRMAX; |
| 74 runtime·memmove((void*)m->notesig, (void*)s, len); |
| 75 |
71 gp->sig = i; | 76 gp->sig = i; |
72 gp->sigpc = ureg->ip; | 77 gp->sigpc = ureg->ip; |
73 | 78 |
74 » » // Only go to runtime·sigpanic if we didn't | 79 » » // Only push runtime·sigpanic if ureg->ip != 0. |
75 » » // panic due to a nil func. | 80 » » // If ureg->ip == 0, probably panicked because of a |
76 » » if(ureg->ip != 0){ | 81 » » // call to a nil func. Not pushing that onto sp will |
77 » » » ureg->ip = (uintptr)runtime·sigpanic; | 82 » » // make the trace look like a call to runtime·sigpanic instead. |
78 » » » return NCONT; | 83 » » // (Otherwise the trace will end at runtime·sigpanic and we |
| 84 » » // won't get to see who faulted.) |
| 85 » » if(ureg->ip != 0) { |
| 86 » » » sp = (uintptr*)ureg->sp; |
| 87 » » » *--sp = ureg->ip; |
| 88 » » » ureg->sp = (uint64)sp; |
79 } | 89 } |
80 » » runtime·goexitsall(""); | 90 » » ureg->ip = (uintptr)runtime·sigpanic; |
81 » » return NDFLT; | 91 » » return NCONT; |
82 } | 92 } |
83 | 93 |
84 if(!(nsig->flags & SigThrow)) | 94 if(!(nsig->flags & SigThrow)) |
85 return NDFLT; | 95 return NDFLT; |
86 | 96 |
87 Throw: | 97 Throw: |
88 runtime·startpanic(); | 98 runtime·startpanic(); |
89 | 99 |
90 » runtime·printf("%s\n", nsig->name); | 100 » runtime·printf("%s\n", s); |
91 runtime·printf("PC=%X\n", ureg->ip); | 101 runtime·printf("PC=%X\n", ureg->ip); |
92 runtime·printf("\n"); | 102 runtime·printf("\n"); |
93 | 103 |
94 if(runtime·gotraceback()) { | 104 if(runtime·gotraceback()) { |
95 runtime·traceback((void*)ureg->ip, (void*)ureg->sp, 0, gp); | 105 runtime·traceback((void*)ureg->ip, (void*)ureg->sp, 0, gp); |
96 runtime·tracebackothers(gp); | 106 runtime·tracebackothers(gp); |
97 runtime·dumpregs(ureg); | 107 runtime·dumpregs(ureg); |
98 } | 108 } |
99 runtime·goexitsall(""); | 109 runtime·goexitsall(""); |
100 runtime·exits(s); | 110 runtime·exits(s); |
101 | 111 |
102 return 0; | 112 return 0; |
103 } | 113 } |
104 | 114 |
105 void | 115 void |
106 runtime·sigenable(uint32 sig) | 116 runtime·sigenable(uint32 sig) |
107 { | 117 { |
108 USED(sig); | 118 USED(sig); |
109 } | 119 } |
110 | 120 |
111 void | 121 void |
112 runtime·resetcpuprofiler(int32 hz) | 122 runtime·resetcpuprofiler(int32 hz) |
113 { | 123 { |
114 // TODO: Enable profiling interrupts. | 124 // TODO: Enable profiling interrupts. |
115 ········ | 125 ········ |
116 m->profilehz = hz; | 126 m->profilehz = hz; |
117 } | 127 } |
LEFT | RIGHT |