OLD | NEW |
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·sigpanic(void); | 9 void runtime·sigpanic(void); |
10 | 10 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 frame.pc = stk->gobuf.pc; | 61 frame.pc = stk->gobuf.pc; |
62 frame.sp = stk->gobuf.sp; | 62 frame.sp = stk->gobuf.sp; |
63 frame.lr = 0; | 63 frame.lr = 0; |
64 frame.fp = 0; | 64 frame.fp = 0; |
65 if(printing && runtime·showframe(nil, gp)) | 65 if(printing && runtime·showframe(nil, gp)) |
66 runtime·printf("----- stack segment boundary ---
--\n"); | 66 runtime·printf("----- stack segment boundary ---
--\n"); |
67 stk = (Stktop*)stk->stackbase; | 67 stk = (Stktop*)stk->stackbase; |
68 ························ | 68 ························ |
69 f = runtime·findfunc(frame.pc); | 69 f = runtime·findfunc(frame.pc); |
70 if(f == nil) { | 70 if(f == nil) { |
71 runtime·printf("runtime: unknown pc %p after sta
ck split\n", frame.pc); | 71 runtime·printf("runtime: unknown pc %p after sta
ck split\n", frame.pc); |
72 » » » » runtime·throw("unknown pc"); | 72 » » » » if(callback != nil) |
| 73 » » » » » runtime·throw("unknown pc"); |
73 } | 74 } |
74 frame.fn = f; | 75 frame.fn = f; |
75 continue; | 76 continue; |
76 } | 77 } |
77 f = frame.fn; | 78 f = frame.fn; |
78 ················ | 79 ················ |
79 // Found an actual function. | 80 // Found an actual function. |
80 // Derive frame pointer and link register. | 81 // Derive frame pointer and link register. |
81 if(frame.fp == 0) | 82 if(frame.fp == 0) |
82 frame.fp = frame.sp + runtime·funcspdelta(f, frame.pc); | 83 frame.fp = frame.sp + runtime·funcspdelta(f, frame.pc); |
83 if(runtime·topofstack(f)) { | 84 if(runtime·topofstack(f)) { |
84 frame.lr = 0; | 85 frame.lr = 0; |
85 flr = nil; | 86 flr = nil; |
86 } else { | 87 } else { |
87 if(frame.lr == 0) | 88 if(frame.lr == 0) |
88 frame.lr = *(uintptr*)frame.sp; | 89 frame.lr = *(uintptr*)frame.sp; |
89 flr = runtime·findfunc(frame.lr); | 90 flr = runtime·findfunc(frame.lr); |
90 if(flr == nil) { | 91 if(flr == nil) { |
91 runtime·printf("runtime: unexpected return pc fo
r %s called from %p\n", runtime·funcname(f), frame.lr); | 92 runtime·printf("runtime: unexpected return pc fo
r %s called from %p\n", runtime·funcname(f), frame.lr); |
92 » » » » runtime·throw("unknown caller pc"); | 93 » » » » if(callback != nil) |
| 94 » » » » » runtime·throw("unknown caller pc"); |
93 } | 95 } |
94 } | 96 } |
95 ························ | 97 ························ |
96 // Derive size of arguments. | 98 // Derive size of arguments. |
97 // Most functions have a fixed-size argument block, | 99 // Most functions have a fixed-size argument block, |
98 // so we can use metadata about the function f. | 100 // so we can use metadata about the function f. |
99 // Not all, though: there are some variadic functions | 101 // Not all, though: there are some variadic functions |
100 // in package runtime, and for those we use call-specific | 102 // in package runtime, and for those we use call-specific |
101 // metadata recorded by f's caller. | 103 // metadata recorded by f's caller. |
102 if(callback != nil || printing) { | 104 if(callback != nil || printing) { |
103 frame.argp = (byte*)frame.fp + sizeof(uintptr); | 105 frame.argp = (byte*)frame.fp + sizeof(uintptr); |
104 if(f->args != ArgsSizeUnknown) | 106 if(f->args != ArgsSizeUnknown) |
105 frame.arglen = f->args; | 107 frame.arglen = f->args; |
106 else if(flr == nil) | 108 else if(flr == nil) |
107 frame.arglen = 0; | 109 frame.arglen = 0; |
108 else if(frame.lr == (uintptr)runtime·lessstack) | 110 else if(frame.lr == (uintptr)runtime·lessstack) |
109 frame.arglen = stk->argsize; | 111 frame.arglen = stk->argsize; |
110 else if((i = runtime·funcarglen(flr, frame.lr)) >= 0) | 112 else if((i = runtime·funcarglen(flr, frame.lr)) >= 0) |
111 frame.arglen = i; | 113 frame.arglen = i; |
112 else { | 114 else { |
113 runtime·printf("runtime: unknown argument frame
size for %s called from %p [%s]\n", | 115 runtime·printf("runtime: unknown argument frame
size for %s called from %p [%s]\n", |
114 runtime·funcname(f), frame.lr, flr ? run
time·funcname(flr) : "?"); | 116 runtime·funcname(f), frame.lr, flr ? run
time·funcname(flr) : "?"); |
115 » » » » if(!printing) | 117 » » » » if(callback != nil) |
116 runtime·throw("invalid stack"); | 118 runtime·throw("invalid stack"); |
117 frame.arglen = 0; | 119 frame.arglen = 0; |
118 } | 120 } |
119 } | 121 } |
120 | 122 |
121 // Derive location and size of local variables. | 123 // Derive location and size of local variables. |
122 if(frame.fp == frame.sp) { | 124 if(frame.fp == frame.sp) { |
123 // Function has not created a frame for itself yet. | 125 // Function has not created a frame for itself yet. |
124 frame.varp = nil; | 126 frame.varp = nil; |
125 frame.varlen = 0; | 127 frame.varlen = 0; |
126 } else if(f->locals == 0) { | 128 } else if(f->locals == 0) { |
127 // Assume no information, so use whole frame. | 129 // Assume no information, so use whole frame. |
128 // TODO: Distinguish local==0 from local==unknown. | 130 // TODO: Distinguish local==0 from local==unknown. |
129 frame.varp = (byte*)frame.sp; | 131 frame.varp = (byte*)frame.sp; |
130 frame.varlen = frame.fp - frame.sp; | 132 frame.varlen = frame.fp - frame.sp; |
131 } else { | 133 } else { |
132 if(f->locals > frame.fp - frame.sp) { | 134 if(f->locals > frame.fp - frame.sp) { |
133 runtime·printf("runtime: inconsistent locals=%p
frame=%p fp=%p sp=%p for %s\n", (uintptr)f->locals, (uintptr)f->frame, frame.fp,
frame.sp, runtime·funcname(f)); | 135 runtime·printf("runtime: inconsistent locals=%p
frame=%p fp=%p sp=%p for %s\n", (uintptr)f->locals, (uintptr)f->frame, frame.fp,
frame.sp, runtime·funcname(f)); |
134 » » » » runtime·throw("invalid stack"); | 136 » » » » if(callback != nil) |
| 137 » » » » » runtime·throw("invalid stack"); |
135 } | 138 } |
136 frame.varp = (byte*)frame.fp - f->locals; | 139 frame.varp = (byte*)frame.fp - f->locals; |
137 frame.varlen = f->locals; | 140 frame.varlen = f->locals; |
138 } | 141 } |
139 | 142 |
140 | 143 |
141 if(skip > 0) { | 144 if(skip > 0) { |
142 skip--; | 145 skip--; |
143 goto skipped; | 146 goto skipped; |
144 } | 147 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 int32 | 256 int32 |
254 runtime·callers(int32 skip, uintptr *pcbuf, int32 m) | 257 runtime·callers(int32 skip, uintptr *pcbuf, int32 m) |
255 { | 258 { |
256 uintptr pc, sp; | 259 uintptr pc, sp; |
257 ········ | 260 ········ |
258 sp = runtime·getcallersp(&skip); | 261 sp = runtime·getcallersp(&skip); |
259 pc = (uintptr)runtime·getcallerpc(&skip); | 262 pc = (uintptr)runtime·getcallerpc(&skip); |
260 | 263 |
261 return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m, nil, nil, fals
e); | 264 return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m, nil, nil, fals
e); |
262 } | 265 } |
OLD | NEW |