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