Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Alfred Persson Forsberg <[email protected]>
  • Loading branch information
alfredfo committed Jul 28, 2022
0 parents commit 399c5a5
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 0 deletions.
140 changes: 140 additions & 0 deletions execinfo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <dlfcn.h>
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define D10(x) ceil(log10(((x) == 0) ? 2 : ((x) + 1)))

inline static void *
realloc_safe(void *ptr, size_t size) {
void *nptr;

nptr = realloc(ptr, size);
if (nptr == NULL)
free(ptr);
return nptr;
}

int backtrace(void** buffer, int size) {
unw_cursor_t cur;
unw_context_t ctx;

unw_getcontext(&ctx);
unw_init_local(&cur, &ctx);
unw_step(&cur); // step over the 'backtrace' call. (this function)
int i = 0;

do {
if (++i == size) {
return i - 1;
}
unw_word_t ip;
unw_get_reg(&cur, UNW_REG_IP, &ip);
buffer[i - 1] = (void*)ip;
} while (unw_step(&cur));
return i - 1;
}

// pasted from resslinux/libexecinfo

char **backtrace_symbols(void *const *buffer, int size) {
size_t clen, alen;
int i, offset;
char **rval;
Dl_info info;

clen = size * sizeof(char *);
rval = malloc(clen);
if (rval == NULL)
return NULL;
for (i = 0; i < size; i++) {
if (dladdr(buffer[i], &info) != 0) {
if (info.dli_sname == NULL) {
info.dli_sname = "???"; // "cannot find symbol name :d ";
}
if (info.dli_saddr == NULL) {
info.dli_saddr = buffer[i];
}
offset = buffer[i] - info.dli_saddr;
/* "0x01234567 <function+offset> at filename" */
alen = 2 + /* "0x" */
(sizeof(void *) * 2) + /* "01234567" */
2 + /* " <" */
strlen(info.dli_sname) + /* "function" */
1 + /* "+" */
10 + /* "offset */
5 + /* "> at " */
strlen(info.dli_fname) + /* "filename" */
1; /* "\0" */
rval = realloc_safe(rval, clen + alen);
if (rval == NULL)
return NULL;
snprintf((char *) rval + clen, alen, "%p <%s+%d> at %s",
buffer[i], info.dli_sname, offset, info.dli_fname);
} else {
alen = 2 + /* "0x" */
(sizeof(void *) * 2) + /* "01234567" */
1; /* "\0" */
rval = realloc_safe(rval, clen + alen);
if (rval == NULL)
return NULL;
snprintf((char *) rval + clen, alen, "%p", buffer[i]);
}
rval[i] = (char *) clen;
clen += alen;
}

for (i = 0; i < size; i++)
rval[i] += (long) rval;

return rval;
}

void backtrace_symbols_fd(void *const *buffer, int size, int fd) {
int i, len, offset;
char *buf;
Dl_info info;

for (i = 0; i < size; i++) {
if (dladdr(buffer[i], &info) != 0) {
if (info.dli_sname == NULL)
info.dli_sname = "???";
if (info.dli_saddr == NULL)
info.dli_saddr = buffer[i];
offset = buffer[i] - info.dli_saddr;
/* "0x01234567 <function+offset> at filename" */
len = 2 + /* "0x" */
(sizeof(void *) * 2) + /* "01234567" */
2 + /* " <" */
strlen(info.dli_sname) + /* "function" */
1 + /* "+" */
D10(offset) + /* "offset */
5 + /* "> at " */
strlen(info.dli_fname) + /* "filename" */
2; /* "\n\0" */
buf = alloca(len);
if (buf == NULL)
return;
snprintf(buf, len, "%p <%s+%d> at %s\n",
buffer[i], info.dli_sname, offset, info.dli_fname);
} else {
len = 2 + /* "0x" */
(sizeof(void *) * 2) + /* "01234567" */
2; /* "\n\0" */
buf = alloca(len);
if (buf == NULL)
return;
snprintf(buf, len, "%p\n", buffer[i]);
}
write(fd, buf, strlen(buf));
}
}
45 changes: 45 additions & 0 deletions execinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2003 Maxim Sobolev <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: execinfo.h,v 1.2 2004/07/19 05:20:29 sobomax Exp $
*/

#ifndef _EXECINFO_H_
#define _EXECINFO_H_

#ifdef __cplusplus
extern "C" {
#endif

int backtrace(void **, int);
char ** backtrace_symbols(void *const *, int);
void backtrace_symbols_fd(void *const *, int, int);
char ** bt_name(void *const *, int, int);

#ifdef __cplusplus
}
#endif

#endif /* _EXECINFO_H_ */
16 changes: 16 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
project('execinfo', 'c', version : '1.0.0')

# pkg = import('pkgconfig')
prog_python = import('python').find_installation('python3')

dep_unwind = dependency('libunwind-generic', required: true)#, required : true)
# deps = [ dep_unwind ]

execinfo = library('execinfo', 'execinfo.c',
dependencies : [dep_unwind],
install : true)

install_headers('execinfo.h')

#pkg.generate(execinfo,
# description : 'Clone of the backtrace facility found in glibc implemented with libunwind')

0 comments on commit 399c5a5

Please sign in to comment.