Added spec:commit task to commit changes to spec/ruby sources.
[rbx.git] / shotgun / lib / missing / backtrace.c
blob96205ce58662aae6c4abc8c5800acb524953f2a2
1 #ifndef backtrace
3 #define RANDOM_FP_THRESHOLD 0x1024
5 #include <stddef.h>
6 #include <sys/types.h>
7 #include <sys/uio.h>
8 #include <dlfcn.h>
9 #include <math.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
15 void *
16 getreturnaddr(int level)
19 switch(level) {
20 case 0: return __builtin_return_address(1);
21 case 1: return __builtin_return_address(2);
22 case 2: return __builtin_return_address(3);
23 case 3: return __builtin_return_address(4);
24 case 4: return __builtin_return_address(5);
25 case 5: return __builtin_return_address(6);
26 case 6: return __builtin_return_address(7);
27 case 7: return __builtin_return_address(8);
28 case 8: return __builtin_return_address(9);
29 case 9: return __builtin_return_address(10);
30 case 10: return __builtin_return_address(11);
31 case 11: return __builtin_return_address(12);
32 case 12: return __builtin_return_address(13);
33 case 13: return __builtin_return_address(14);
34 case 14: return __builtin_return_address(15);
35 case 15: return __builtin_return_address(16);
36 case 16: return __builtin_return_address(17);
37 case 17: return __builtin_return_address(18);
38 case 18: return __builtin_return_address(19);
39 case 19: return __builtin_return_address(20);
40 case 20: return __builtin_return_address(21);
41 case 21: return __builtin_return_address(22);
42 case 22: return __builtin_return_address(23);
43 case 23: return __builtin_return_address(24);
44 case 24: return __builtin_return_address(25);
45 case 25: return __builtin_return_address(26);
46 case 26: return __builtin_return_address(27);
47 case 27: return __builtin_return_address(28);
48 case 28: return __builtin_return_address(29);
49 case 29: return __builtin_return_address(30);
50 case 30: return __builtin_return_address(31);
51 case 31: return __builtin_return_address(32);
52 case 32: return __builtin_return_address(33);
53 case 33: return __builtin_return_address(34);
54 case 34: return __builtin_return_address(35);
55 case 35: return __builtin_return_address(36);
56 case 36: return __builtin_return_address(37);
57 case 37: return __builtin_return_address(38);
58 case 38: return __builtin_return_address(39);
59 case 39: return __builtin_return_address(40);
60 case 40: return __builtin_return_address(41);
61 case 41: return __builtin_return_address(42);
62 case 42: return __builtin_return_address(43);
63 case 43: return __builtin_return_address(44);
64 case 44: return __builtin_return_address(45);
65 case 45: return __builtin_return_address(46);
66 case 46: return __builtin_return_address(47);
67 case 47: return __builtin_return_address(48);
68 case 48: return __builtin_return_address(49);
69 case 49: return __builtin_return_address(50);
70 case 50: return __builtin_return_address(51);
71 case 51: return __builtin_return_address(52);
72 case 52: return __builtin_return_address(53);
73 case 53: return __builtin_return_address(54);
74 case 54: return __builtin_return_address(55);
75 case 55: return __builtin_return_address(56);
76 case 56: return __builtin_return_address(57);
77 case 57: return __builtin_return_address(58);
78 case 58: return __builtin_return_address(59);
79 case 59: return __builtin_return_address(60);
80 case 60: return __builtin_return_address(61);
81 case 61: return __builtin_return_address(62);
82 case 62: return __builtin_return_address(63);
83 case 63: return __builtin_return_address(64);
84 case 64: return __builtin_return_address(65);
85 case 65: return __builtin_return_address(66);
86 case 66: return __builtin_return_address(67);
87 case 67: return __builtin_return_address(68);
88 case 68: return __builtin_return_address(69);
89 case 69: return __builtin_return_address(70);
90 case 70: return __builtin_return_address(71);
91 case 71: return __builtin_return_address(72);
92 case 72: return __builtin_return_address(73);
93 case 73: return __builtin_return_address(74);
94 case 74: return __builtin_return_address(75);
95 case 75: return __builtin_return_address(76);
96 case 76: return __builtin_return_address(77);
97 case 77: return __builtin_return_address(78);
98 case 78: return __builtin_return_address(79);
99 case 79: return __builtin_return_address(80);
100 case 80: return __builtin_return_address(81);
101 case 81: return __builtin_return_address(82);
102 case 82: return __builtin_return_address(83);
103 case 83: return __builtin_return_address(84);
104 case 84: return __builtin_return_address(85);
105 case 85: return __builtin_return_address(86);
106 case 86: return __builtin_return_address(87);
107 case 87: return __builtin_return_address(88);
108 case 88: return __builtin_return_address(89);
109 case 89: return __builtin_return_address(90);
110 case 90: return __builtin_return_address(91);
111 case 91: return __builtin_return_address(92);
112 case 92: return __builtin_return_address(93);
113 case 93: return __builtin_return_address(94);
114 case 94: return __builtin_return_address(95);
115 case 95: return __builtin_return_address(96);
116 case 96: return __builtin_return_address(97);
117 case 97: return __builtin_return_address(98);
118 case 98: return __builtin_return_address(99);
119 case 99: return __builtin_return_address(100);
120 case 100: return __builtin_return_address(101);
121 case 101: return __builtin_return_address(102);
122 case 102: return __builtin_return_address(103);
123 case 103: return __builtin_return_address(104);
124 case 104: return __builtin_return_address(105);
125 case 105: return __builtin_return_address(106);
126 case 106: return __builtin_return_address(107);
127 case 107: return __builtin_return_address(108);
128 case 108: return __builtin_return_address(109);
129 case 109: return __builtin_return_address(110);
130 case 110: return __builtin_return_address(111);
131 case 111: return __builtin_return_address(112);
132 case 112: return __builtin_return_address(113);
133 case 113: return __builtin_return_address(114);
134 case 114: return __builtin_return_address(115);
135 case 115: return __builtin_return_address(116);
136 case 116: return __builtin_return_address(117);
137 case 117: return __builtin_return_address(118);
138 case 118: return __builtin_return_address(119);
139 case 119: return __builtin_return_address(120);
140 case 120: return __builtin_return_address(121);
141 case 121: return __builtin_return_address(122);
142 case 122: return __builtin_return_address(123);
143 case 123: return __builtin_return_address(124);
144 case 124: return __builtin_return_address(125);
145 case 125: return __builtin_return_address(126);
146 case 126: return __builtin_return_address(127);
147 case 127: return __builtin_return_address(128);
148 default: return NULL;
152 void *
153 getframeaddr(int level)
156 switch(level) {
157 case 0: return __builtin_frame_address(1);
158 case 1: return __builtin_frame_address(2);
159 case 2: return __builtin_frame_address(3);
160 case 3: return __builtin_frame_address(4);
161 case 4: return __builtin_frame_address(5);
162 case 5: return __builtin_frame_address(6);
163 case 6: return __builtin_frame_address(7);
164 case 7: return __builtin_frame_address(8);
165 case 8: return __builtin_frame_address(9);
166 case 9: return __builtin_frame_address(10);
167 case 10: return __builtin_frame_address(11);
168 case 11: return __builtin_frame_address(12);
169 case 12: return __builtin_frame_address(13);
170 case 13: return __builtin_frame_address(14);
171 case 14: return __builtin_frame_address(15);
172 case 15: return __builtin_frame_address(16);
173 case 16: return __builtin_frame_address(17);
174 case 17: return __builtin_frame_address(18);
175 case 18: return __builtin_frame_address(19);
176 case 19: return __builtin_frame_address(20);
177 case 20: return __builtin_frame_address(21);
178 case 21: return __builtin_frame_address(22);
179 case 22: return __builtin_frame_address(23);
180 case 23: return __builtin_frame_address(24);
181 case 24: return __builtin_frame_address(25);
182 case 25: return __builtin_frame_address(26);
183 case 26: return __builtin_frame_address(27);
184 case 27: return __builtin_frame_address(28);
185 case 28: return __builtin_frame_address(29);
186 case 29: return __builtin_frame_address(30);
187 case 30: return __builtin_frame_address(31);
188 case 31: return __builtin_frame_address(32);
189 case 32: return __builtin_frame_address(33);
190 case 33: return __builtin_frame_address(34);
191 case 34: return __builtin_frame_address(35);
192 case 35: return __builtin_frame_address(36);
193 case 36: return __builtin_frame_address(37);
194 case 37: return __builtin_frame_address(38);
195 case 38: return __builtin_frame_address(39);
196 case 39: return __builtin_frame_address(40);
197 case 40: return __builtin_frame_address(41);
198 case 41: return __builtin_frame_address(42);
199 case 42: return __builtin_frame_address(43);
200 case 43: return __builtin_frame_address(44);
201 case 44: return __builtin_frame_address(45);
202 case 45: return __builtin_frame_address(46);
203 case 46: return __builtin_frame_address(47);
204 case 47: return __builtin_frame_address(48);
205 case 48: return __builtin_frame_address(49);
206 case 49: return __builtin_frame_address(50);
207 case 50: return __builtin_frame_address(51);
208 case 51: return __builtin_frame_address(52);
209 case 52: return __builtin_frame_address(53);
210 case 53: return __builtin_frame_address(54);
211 case 54: return __builtin_frame_address(55);
212 case 55: return __builtin_frame_address(56);
213 case 56: return __builtin_frame_address(57);
214 case 57: return __builtin_frame_address(58);
215 case 58: return __builtin_frame_address(59);
216 case 59: return __builtin_frame_address(60);
217 case 60: return __builtin_frame_address(61);
218 case 61: return __builtin_frame_address(62);
219 case 62: return __builtin_frame_address(63);
220 case 63: return __builtin_frame_address(64);
221 case 64: return __builtin_frame_address(65);
222 case 65: return __builtin_frame_address(66);
223 case 66: return __builtin_frame_address(67);
224 case 67: return __builtin_frame_address(68);
225 case 68: return __builtin_frame_address(69);
226 case 69: return __builtin_frame_address(70);
227 case 70: return __builtin_frame_address(71);
228 case 71: return __builtin_frame_address(72);
229 case 72: return __builtin_frame_address(73);
230 case 73: return __builtin_frame_address(74);
231 case 74: return __builtin_frame_address(75);
232 case 75: return __builtin_frame_address(76);
233 case 76: return __builtin_frame_address(77);
234 case 77: return __builtin_frame_address(78);
235 case 78: return __builtin_frame_address(79);
236 case 79: return __builtin_frame_address(80);
237 case 80: return __builtin_frame_address(81);
238 case 81: return __builtin_frame_address(82);
239 case 82: return __builtin_frame_address(83);
240 case 83: return __builtin_frame_address(84);
241 case 84: return __builtin_frame_address(85);
242 case 85: return __builtin_frame_address(86);
243 case 86: return __builtin_frame_address(87);
244 case 87: return __builtin_frame_address(88);
245 case 88: return __builtin_frame_address(89);
246 case 89: return __builtin_frame_address(90);
247 case 90: return __builtin_frame_address(91);
248 case 91: return __builtin_frame_address(92);
249 case 92: return __builtin_frame_address(93);
250 case 93: return __builtin_frame_address(94);
251 case 94: return __builtin_frame_address(95);
252 case 95: return __builtin_frame_address(96);
253 case 96: return __builtin_frame_address(97);
254 case 97: return __builtin_frame_address(98);
255 case 98: return __builtin_frame_address(99);
256 case 99: return __builtin_frame_address(100);
257 case 100: return __builtin_frame_address(101);
258 case 101: return __builtin_frame_address(102);
259 case 102: return __builtin_frame_address(103);
260 case 103: return __builtin_frame_address(104);
261 case 104: return __builtin_frame_address(105);
262 case 105: return __builtin_frame_address(106);
263 case 106: return __builtin_frame_address(107);
264 case 107: return __builtin_frame_address(108);
265 case 108: return __builtin_frame_address(109);
266 case 109: return __builtin_frame_address(110);
267 case 110: return __builtin_frame_address(111);
268 case 111: return __builtin_frame_address(112);
269 case 112: return __builtin_frame_address(113);
270 case 113: return __builtin_frame_address(114);
271 case 114: return __builtin_frame_address(115);
272 case 115: return __builtin_frame_address(116);
273 case 116: return __builtin_frame_address(117);
274 case 117: return __builtin_frame_address(118);
275 case 118: return __builtin_frame_address(119);
276 case 119: return __builtin_frame_address(120);
277 case 120: return __builtin_frame_address(121);
278 case 121: return __builtin_frame_address(122);
279 case 122: return __builtin_frame_address(123);
280 case 123: return __builtin_frame_address(124);
281 case 124: return __builtin_frame_address(125);
282 case 125: return __builtin_frame_address(126);
283 case 126: return __builtin_frame_address(127);
284 case 127: return __builtin_frame_address(128);
285 default: return NULL;
289 * Copyright (c) 2003 Maxim Sobolev <sobomax@FreeBSD.org>
290 * All rights reserved.
292 * Redistribution and use in source and binary forms, with or without
293 * modification, are permitted provided that the following conditions
294 * are met:
295 * 1. Redistributions of source code must retain the above copyright
296 * notice, this list of conditions and the following disclaimer.
297 * 2. Redistributions in binary form must reproduce the above copyright
298 * notice, this list of conditions and the following disclaimer in the
299 * documentation and/or other materials provided with the distribution.
301 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
302 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
303 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
304 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
305 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
306 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
307 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
308 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
309 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
310 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311 * SUCH DAMAGE.
313 * $Id: execinfo.c,v 1.3 2004/07/19 05:21:09 sobomax Exp $
317 #define D10(x) ceil(log10(((x) == 0) ? 2 : ((x) + 1)))
319 inline static void *
320 realloc_safe(void *ptr, size_t size)
322 void *nptr;
324 nptr = realloc(ptr, size);
325 if (nptr == NULL)
326 free(ptr);
327 return nptr;
330 extern void *__main_address;
333 backtrace(void **buffer, int size)
335 int i, idx;
336 void *fp;
338 size += 1;
340 idx = 0;
341 for (i = 1; i < size; i++) {
342 fp = getframeaddr(i);
343 if(!fp || fp == __main_address) break;
344 buffer[idx++] = getreturnaddr(i);
345 if (buffer[i] == NULL)
346 break;
349 return idx - 1;
352 char **
353 backtrace_symbols(void *const *buffer, int size)
355 int i, clen, alen, offset;
356 char **rval;
357 char *cp;
358 char **_list;
359 Dl_info info;
361 clen = size * sizeof(char *);
362 rval = malloc(clen);
363 if (rval == NULL)
364 return NULL;
365 _list = (char**)cp;
366 _list = &(rval[size]);
367 for (i = 0; i < size; i++) {
368 if (dladdr(buffer[i], &info) != 0) {
369 if (info.dli_sname == NULL)
370 info.dli_sname = "???";
371 if (info.dli_saddr == NULL)
372 info.dli_saddr = buffer[i];
373 offset = buffer[i] - info.dli_saddr;
374 /* "0x01234567 <function+offset> at filename" */
375 alen = 2 + /* "0x" */
376 (sizeof(void *) * 2) + /* "01234567" */
377 2 + /* " <" */
378 strlen(info.dli_sname) + /* "function" */
379 1 + /* "+" */
380 D10(offset) + /* "offset */
381 5 + /* "> at " */
382 strlen(info.dli_fname) + /* "filename" */
383 1; /* "\0" */
384 rval = realloc_safe(rval, clen + alen);
385 if (rval == NULL)
386 return NULL;
387 snprintf(cp, alen, "%10p <%s+%d> at %s",
388 buffer[i], info.dli_sname, offset, info.dli_fname);
389 } else {
390 alen = 2 + /* "0x" */
391 (sizeof(void *) * 2) + /* "01234567" */
392 1; /* "\0" */
393 rval = realloc_safe(rval, clen + alen);
394 if (rval == NULL)
395 return NULL;
396 snprintf(cp, alen, "%p", buffer[i]);
398 rval[i] = cp;
399 cp += alen;
402 return rval;
405 void
406 backtrace_symbols_fd(void *const *buffer, int size, int fd)
408 int i, len, offset;
409 char *buf;
410 Dl_info info;
412 for (i = 0; i < size; i++) {
413 if (dladdr(buffer[i], &info) != 0) {
414 if (info.dli_sname == NULL)
415 info.dli_sname = "???";
416 if (info.dli_saddr == NULL)
417 info.dli_saddr = buffer[i];
418 offset = buffer[i] - info.dli_saddr;
419 /* "0x01234567 <function+offset> at filename" */
420 len = 2 + /* "0x" */
421 (sizeof(void *) * 2) + /* "01234567" */
422 2 + /* " <" */
423 strlen(info.dli_sname) + /* "function" */
424 1 + /* "+" */
425 D10(offset) + /* "offset */
426 5 + /* "> at " */
427 strlen(info.dli_fname) + /* "filename" */
428 2; /* "\n\0" */
429 buf = alloca(len);
430 if (buf == NULL)
431 return;
432 snprintf(buf, len, "%10p <%s+%d> at %s\n",
433 buffer[i], info.dli_sname, offset, info.dli_fname);
434 } else {
435 len = 2 + /* "0x" */
436 (sizeof(void *) * 2) + /* "01234567" */
437 2; /* "\n\0" */
438 buf = alloca(len);
439 if (buf == NULL)
440 return;
441 snprintf(buf, len, "%p <unknown location>\n", buffer[i]);
443 write(fd, buf, len - 1);
447 #endif