Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libexecinfo Add a similar to linux backtrace_* and execi...



details:   https://anonhg.NetBSD.org/src/rev/22a25a24fb9f
branches:  trunk
changeset: 779409:22a25a24fb9f
user:      christos <christos%NetBSD.org@localhost>
date:      Sat May 26 22:02:29 2012 +0000

description:
Add a similar to linux backtrace_* and execinfo.h family of functions

diffstat:

 lib/libexecinfo/Makefile      |   31 +++++
 lib/libexecinfo/backtrace.3   |  161 +++++++++++++++++++++++++++++
 lib/libexecinfo/backtrace.c   |  227 ++++++++++++++++++++++++++++++++++++++++++
 lib/libexecinfo/builtin.c     |   68 ++++++++++++
 lib/libexecinfo/execinfo.h    |   42 +++++++
 lib/libexecinfo/shlib_version |    3 +
 lib/libexecinfo/symtab.c      |  192 +++++++++++++++++++++++++++++++++++
 lib/libexecinfo/symtab.h      |   42 +++++++
 lib/libexecinfo/unwind.c      |   72 +++++++++++++
 lib/libexecinfo/unwind.h      |   68 ++++++++++++
 10 files changed, 906 insertions(+), 0 deletions(-)

diffs (truncated from 946 to 300 lines):

diff -r 1e4534f21b9c -r 22a25a24fb9f lib/libexecinfo/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libexecinfo/Makefile  Sat May 26 22:02:29 2012 +0000
@@ -0,0 +1,31 @@
+# $NetBSD: Makefile,v 1.1 2012/05/26 22:02:29 christos Exp $
+
+.include <bsd.own.mk>
+
+USE_UNWIND=yes
+WARNS?=4
+INCSDIR=/usr/include
+INCS=execinfo.h
+
+#CPPFLAGS+='-D__RCSID(a)=' -D_GNU_SOURCE '-D__printflike(a,b)='
+#CPPFLAGS+=-I/usr/include/libelf
+#COPTS+=-std=gnu99
+
+LIBDPLIBS+= elf        ${NETBSDSRCDIR}/external/bsd/libelf/lib
+
+LIB=execinfo
+SRCS=symtab.c backtrace.c
+MAN= backtrace.3
+
+.if ${USE_UNWIND} == "yes"
+SRCS+=unwind.c
+.else
+SRCS+=builtin.c
+.endif
+
+MLINKS+= backtrace.3 backtrace_symbols.3
+MLINKS+= backtrace.3 backtrace_symbols_fmt.3
+MLINKS+= backtrace.3 backtrace_symbols_fd.3
+MLINKS+= backtrace.3 backtrace_symbols_fd_fmt.3
+
+.include <bsd.lib.mk>
diff -r 1e4534f21b9c -r 22a25a24fb9f lib/libexecinfo/backtrace.3
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libexecinfo/backtrace.3       Sat May 26 22:02:29 2012 +0000
@@ -0,0 +1,161 @@
+.\"    $NetBSD: backtrace.3,v 1.1 2012/05/26 22:02:29 christos Exp $
+.\"
+.\" Copyright (c) 2012 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Christos Zoulas
+.\"
+.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+.\"
+.Dd January 24, 2012
+.Dt BACKTRACE 3
+.Os
+.Sh NAME
+.Nm backtrace
+.Nd fill in the backtrace of the currently executing thread.
+.Sh LIBRARY
+.Lb libexecinfo
+.Sh SYNOPSIS
+.In execinfo.h
+.Ft size_t
+.Fn backtrace "void **addrlist" "size_t len"
+.Ft "char **"
+.Fn backtrace_symbols "void * const *addrlist" "size_t len"
+.Ft int
+.Fn backtrace_symbols_fd "void * const *addrlist" "size_t len" "int fd"
+.Ft "char **"
+.Fn backtrace_symbols_fmt "void * const *addrlist" "size_t len" "const char *fmt"
+.Ft int
+.Fn backtrace_symbols_fmt_fd "void * const *addrlist" "size_t len" "const char *fmt" "int fd"
+.Sh DESCRIPTION
+The
+.Fn backtrace
+function places into the array pointed by
+.Fa addrlist
+the array of the values of the program counter for each frame called up to
+.Fa len
+frames.
+The number of frames found (which can be fewer than
+.Fa len )
+is returned.
+.Pp
+The
+.Fn backtrace_symbols_fmt
+function, takes an array of previously filled addresses from
+.Fn backtrace
+in
+.Fa addrlist
+of
+.Fa len
+elements, and uses
+.Fa fmt
+to format them.
+The formatting characters available are:
+.Bl -tag -width a -offset indent
+.It Dv a
+The numeric address of each element as would be printed using %p.
+.It Dv n
+The name of the nearest function symbol (smaller than the address element)
+as determined by
+.Xr dladdr 3
+if the symbol was dynamic, or looked up in the executable if static and
+the /proc filesystem is available to determine the executable path.
+.It Dv d
+The difference of the symbol address and the address element printed
+using 0x%tx.
+.It Dv D
+The difference of the symbol addresss and the address element printed using
++0x%tx if non-zero, or nothing if zero.
+.It Dv f
+The filename of the symbol as determined by
+.Xr dladdr 3 .
+.El
+.Pp
+The array of formatted strings is returned as a contiguous memory address which
+can be freed by a single
+.Xr free 3 .
+.Pp
+The
+.Fn backtrace_symbols
+function is equivalent of calling
+.Fn backtrace_symbols_fmt
+with a format argument of
+.Dv "%a <%n%D> at %f"
+.Pp
+The
+.Fn backtrace_symbols_fd
+and
+.Fn backtrace_symbols_fmt_fd
+are similar to the non _fd named functions, only instead of returning
+an array or strings, they print a new-line separated array of strings in
+fd, and return
+.Dv 0
+on success and
+.Dv \-1
+on failure.
+.Sh RETURN VALUES
+The
+.Fn backtrace
+function returns the number of elements tht were filled in the backtrace.
+The
+.Fn backtrace_symbols
+and
+.Fn backtrace_symbols_fmt
+return a string array on success, and
+.Dv NULL
+on failure, setting
+.Va errno .
+.\" XXX
+Diagnostic output may also be produced, by the ELF symbol lookup functions.
+function returns a pointer to a string that is the parent directory of
+.Sh BUGS
+.Bl -enum
+.It
+Errors should not be printed but communicated to the caller differently.
+.It
+Because these functions use
+.Xr elf 3
+this is a separate library instead of be part of libc/libutil so that library
+dependencies are not introduced.
+.It
+The linux versions of the functions (there are no _fmt variants), use
+.Ft int
+instead of
+.Ft size_t
+arguments.
+.It
+Since
+.Xr dladdr 3
+only deals with dynamic symbols, we need to find the symbols from the main
+portion of the program.
+For that we need to locate the executable, and we use procfs for to find it
+which is not portable.
+.El
+.Sh SEE ALSO
+.Xr elf 3
+.Xr dladdr 3
+.Sh HISTORY
+The
+.Fn backtrace
+library of functions first appeared in
+.Nx 6 .
diff -r 1e4534f21b9c -r 22a25a24fb9f lib/libexecinfo/backtrace.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libexecinfo/backtrace.c       Sat May 26 22:02:29 2012 +0000
@@ -0,0 +1,227 @@
+/*     $NetBSD: backtrace.c,v 1.1 2012/05/26 22:02:29 christos Exp $   */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: backtrace.c,v 1.1 2012/05/26 22:02:29 christos Exp $");
+
+#include <sys/param.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <elf.h>
+
+#include "execinfo.h"
+#include "symtab.h"
+
+#ifdef __linux__
+#define SELF   "/proc/self/exe"
+#else
+#define SELF   "/proc/curproc/file"
+#endif
+
+static int __printflike(4, 5)
+rasprintf(char **buf, size_t *bufsiz, size_t offs, const char *fmt, ...)
+{
+       for (;;) {
+               size_t nbufsiz;
+               char *nbuf;
+
+               if (*buf && offs < *bufsiz) {
+                       va_list ap;
+                       int len;
+
+                       va_start(ap, fmt);
+                       len = vsnprintf(*buf + offs, *bufsiz - offs, fmt, ap);
+                       va_end(ap);
+
+                       if (len < 0 || (size_t)len < *bufsiz - offs)
+                               return len;
+                       nbufsiz = MAX(*bufsiz + 512, (size_t)len + 1);
+               } else
+                       nbufsiz = MAX(offs, *bufsiz) + 512;
+                       
+               nbuf = realloc(*buf, nbufsiz);
+               if (nbuf == NULL)
+                       return -1;
+               *buf = nbuf;
+               *bufsiz = nbufsiz;
+       }
+}
+
+/*
+ * format specifiers:
+ *     %a      = address
+ *     %n      = symbol_name
+ *     %d      = symbol_address - address
+ *     %D      = if symbol_address == address "" else +%d
+ *     %f      = filename
+ */
+static ssize_t
+format_string(char **buf, size_t *bufsiz, size_t offs, const char *fmt,
+    Dl_info *dli, const void *addr)
+{



Home | Main Index | Thread Index | Old Index