Commit eff02e4f by Ian Lance Taylor Committed by Ian Lance Taylor

libbacktrace/:

	* Initial implementation.

./:
	* MAINTAINERS (Various Maintainers): Add libbacktrace.
	* configure.ac (host_libs): Add libbacktrace.
	(target_libraries): Add libbacktrace.
	* Makefile.def (host_modules): Add libbacktrace.
	(target_modules): Likewise.
	* configure, Makefile.in: Rebuild.

gcc/go:
	* config-lang.in (target_libs): Add target-libbacktrace.

From-SVN: r191397
parent 142c8954
2012-09-17 Ian Lance Taylor <iant@google.com>
* MAINTAINERS (Various Maintainers): Add libbacktrace.
* configure.ac (host_libs): Add libbacktrace.
(target_libraries): Add libbacktrace.
* Makefile.def (host_modules): Add libbacktrace.
(target_modules): Likewise.
* configure, Makefile.in: Rebuild.
2012-09-14 David Edelsohn <dje.gcc@gmail.com>
PR target/38607
......
......@@ -155,6 +155,7 @@ objective-c/c++ Stan Shebs stanshebs@earthlink.net
Various Maintainers
libbacktrace Ian Lance Taylor ian@airs.com
libcpp Per Bothner per@bothner.com
libcpp All C and C++ front end maintainers
fp-bit Ian Lance Taylor ian@airs.com
......
......@@ -80,6 +80,7 @@ host_modules= { module= tcl;
missing=mostlyclean; };
host_modules= { module= itcl; };
host_modules= { module= ld; bootstrap=true; };
host_modules= { module= libbacktrace; bootstrap=true; };
host_modules= { module= libcpp; bootstrap=true; };
host_modules= { module= libdecnumber; bootstrap=true; };
host_modules= { module= libgui; };
......@@ -121,6 +122,7 @@ target_modules = { module= libmudflap; lib_path=.libs; };
target_modules = { module= libssp; lib_path=.libs; };
target_modules = { module= newlib; };
target_modules = { module= libgcc; bootstrap=true; no_check=true; };
target_modules = { module= libbacktrace; };
target_modules = { module= libquadmath; };
target_modules = { module= libgfortran; };
target_modules = { module= libobjc; };
......
......@@ -2698,7 +2698,7 @@ build_tools="build-texinfo build-flex build-bison build-m4 build-fixincludes"
# these libraries are used by various programs built for the host environment
#
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktrace libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
......@@ -2717,6 +2717,7 @@ libgcj="target-libffi \
# the host libraries and the host tools (which may be a cross compiler)
# Note that libiberty is not a target library.
target_libraries="target-libgcc \
target-libbacktrace \
target-libgloss \
target-newlib \
target-libgomp \
......
......@@ -133,7 +133,7 @@ build_tools="build-texinfo build-flex build-bison build-m4 build-fixincludes"
# these libraries are used by various programs built for the host environment
#
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
host_libs="intl libiberty opcodes bfd readline tcl tk itcl libgui zlib libbacktrace libcpp libdecnumber gmp mpfr mpc isl cloog libelf libiconv"
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
......@@ -152,6 +152,7 @@ libgcj="target-libffi \
# the host libraries and the host tools (which may be a cross compiler)
# Note that libiberty is not a target library.
target_libraries="target-libgcc \
target-libbacktrace \
target-libgloss \
target-newlib \
target-libgomp \
......
2012-09-17 Ian Lance Taylor <iant@google.com>
* config-lang.in (target_libs): Add target-libbacktrace.
2012-09-16 Ian Lance Taylor <iant@google.com>
* Make-lang.in (go/gogo.o): Depend on filenames.h.
......
......@@ -28,7 +28,7 @@ language="go"
compilers="go1\$(exeext)"
target_libs="target-libgo target-libffi"
target_libs="target-libgo target-libffi target-libbacktrace"
# The Go frontend is written in C++, so we need to build the C++
# compiler during stage 1.
......
2012-09-17 Ian Lance Taylor <iant@google.com>
* Initial implementation.
# Makefile.am -- Backtrace Makefile.
# Copyright (C) 2012 Free Software Foundation, Inc.
# 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.
# (3) The name of the author may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
ACLOCAL_AMFLAGS = -I .. -I ../config
AM_CFLAGS = $(WARN_FLAGS) $(PIC_FLAG) -I $(srcdir)/../include -I ../libgcc
noinst_LTLIBRARIES = libbacktrace.la
libbacktrace_la_SOURCES = \
backtrace.h \
dwarf.c \
fileline.c \
internal.h \
posix.c \
print.c \
state.c
BACKTRACE_FILES = \
backtrace.c \
simple.c \
nounwind.c
FORMAT_FILES = \
elf.c \
unknown.c
VIEW_FILES = \
read.c \
mmapio.c
ALLOC_FILES = \
alloc.c \
mmap.c
EXTRA_libbacktrace_la_SOURCES = \
$(BACKTRACE_FILES) \
$(FORMAT_FILES) \
$(VIEW_FILES) \
$(ALLOC_FILES)
libbacktrace_la_LIBADD = \
$(BACKTRACE_FILE) \
$(FORMAT_FILE) \
$(VIEW_FILE) \
$(ALLOC_FILE)
libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
# Testsuite.
check_PROGRAMS =
TESTS = $(check_PROGRAMS)
if NATIVE
btest_SOURCES = btest.c
btest_CFLAGS = $(AM_CFLAGS) -g -O
btest_LDADD = libbacktrace.la
check_PROGRAMS += btest
endif NATIVE
The libbacktrace library
Initially written by Ian Lance Taylor <iant@google.com>
The libbacktrace library may be linked into a program or library and
used to produce symbolic backtraces. Sample uses would be to print a
detailed backtrace when an error occurs or to gather detailed
profiling information.
The libbacktrace library is provided under a BSD license. See the
source files for the exact license text.
The public functions are declared and documented in the header file
backtrace.h, which should be #include'd by a user of the library.
Building libbacktrace will generate a file backtrace-supported.h,
which a user of the library may use to determine whether backtraces
will work. See the source file backtrace-supported.h.in for the
macros that it defines.
As of September 2012, libbacktrace only supports ELF executables with
DWARF debugging information. The library is written to make it
straightforward to add support for other object file and debugging
formats.
/* alloc.c -- Memory allocation without mmap.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <errno.h>
#include <stdlib.h>
#include "backtrace.h"
#include "internal.h"
/* Allocation routines to use on systems that do not support anonymous
mmap. This implementation just uses malloc, which means that the
backtrace functions may not be safely invoked from a signal
handler. */
/* Allocate memory like malloc. */
void *
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
size_t size, backtrace_error_callback error_callback,
void *data)
{
void *ret;
ret = malloc (size);
if (ret == NULL)
error_callback (data, "malloc", errno);
return ret;
}
/* Free memory. */
void
backtrace_free (struct backtrace_state *state ATTRIBUTE_UNUSED,
void *p, size_t size ATTRIBUTE_UNUSED,
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED)
{
free (p);
}
/* Grow VEC by SIZE bytes. */
void *
backtrace_vector_grow (struct backtrace_state *state ATTRIBUTE_UNUSED,
size_t size, backtrace_error_callback error_callback,
void *data, struct backtrace_vector *vec)
{
void *ret;
if (size > vec->alc)
{
size_t alc;
void *base;
if (vec->size == 0)
alc = 32 * size;
else if (vec->size >= 4096)
alc = vec->size + 4096;
else
alc = 2 * vec->size;
if (alc < vec->size + size)
alc = vec->size + size;
base = realloc (vec->base, alc);
if (base == NULL)
{
error_callback (data, "realloc", errno);
return NULL;
}
vec->base = base;
vec->alc = alc - vec->size;
}
ret = (char *) vec->base + vec->size;
vec->size += size;
vec->alc -= size;
return ret;
}
/* Finish the current allocation on VEC. */
void
backtrace_vector_finish (struct backtrace_state *state ATTRIBUTE_UNUSED,
struct backtrace_vector *vec)
{
vec->base = (char *) vec->base + vec->size;
vec->size = 0;
}
/* Release any extra space allocated for VEC. */
int
backtrace_vector_release (struct backtrace_state *state ATTRIBUTE_UNUSED,
struct backtrace_vector *vec,
backtrace_error_callback error_callback,
void *data)
{
vec->base = realloc (vec->base, vec->size);
if (vec->base == NULL)
{
error_callback (data, "realloc", errno);
return 0;
}
vec->alc = 0;
return 1;
}
/* backtrace-supported.h.in -- Whether stack backtrace is supported.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */
/* The file backtrace-supported.h.in is used by configure to generate
the file backtrace-supported.h. The file backtrace-supported.h may
be #include'd to see whether the backtrace library will be able to
get a backtrace and produce symbolic information. */
/* BACKTRACE_SUPPORTED will be #define'd as 1 if the backtrace library
should work, 0 if it will not. Libraries may #include this to make
other arrangements. */
#define BACKTRACE_SUPPORTED @BACKTRACE_SUPPORTED@
/* BACKTRACE_USES_MALLOC will be #define'd as 1 if the backtrace
library will call malloc as it works, 0 if it will call mmap
instead. This may be used to determine whether it is safe to call
the backtrace functions from a signal handler. In general this
only applies to calls like backtrace and backtrace_pcinfo. It does
not apply to backtrace_simple, which never calls malloc. It does
not apply to backtrace_print, which always calls fprintf and
therefore malloc. */
#define BACKTRACE_USES_MALLOC @BACKTRACE_USES_MALLOC@
/* BACKTRACE_SUPPORTS_THREADS will be #define'd as 1 if the backtrace
library is configured with threading support, 0 if not. If this is
0, the threaded parameter to backtrace_create_state must be passed
as 0. */
#define BACKTRACE_SUPPORTS_THREADS @BACKTRACE_SUPPORTS_THREADS@
/* backtrace.c -- Entry point for stack backtrace library.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include "unwind.h"
#include "backtrace.h"
/* The main backtrace_full routine. */
/* Data passed through _Unwind_Backtrace. */
struct backtrace_data
{
/* Number of frames to skip. */
int skip;
/* Library state. */
struct backtrace_state *state;
/* Callback routine. */
backtrace_full_callback callback;
/* Error callback routine. */
backtrace_error_callback error_callback;
/* Data to pass to callback routines. */
void *data;
/* Value to return from backtrace_full. */
int ret;
};
/* Unwind library callback routine. This is passed to
_Unwind_Backtrace. */
static _Unwind_Reason_Code
unwind (struct _Unwind_Context *context, void *vdata)
{
struct backtrace_data *bdata = (struct backtrace_data *) vdata;
uintptr_t pc;
int ip_before_insn = 0;
#ifdef HAVE_GETIPINFO
pc = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
pc = _Unwind_GetIP (context);
#endif
if (bdata->skip > 0)
{
--bdata->skip;
return _URC_NO_REASON;
}
if (!ip_before_insn)
--pc;
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
bdata->error_callback, bdata->data);
if (bdata->ret != 0)
return _URC_END_OF_STACK;
return _URC_NO_REASON;
}
/* Get a stack backtrace. */
int
backtrace_full (struct backtrace_state *state, int skip,
backtrace_full_callback callback,
backtrace_error_callback error_callback, void *data)
{
struct backtrace_data bdata;
bdata.skip = skip + 1;
bdata.state = state;
bdata.callback = callback;
bdata.error_callback = error_callback;
bdata.data = data;
bdata.ret = 0;
_Unwind_Backtrace (unwind, &bdata);
return bdata.ret;
}
/* backtrace.h -- Public header file for stack backtrace library.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */
#ifndef BACKTRACE_H
#define BACKTRACE_H
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* The backtrace state. This struct is intentionally not defined in
the public interface. */
struct backtrace_state;
/* The type of the error callback argument to backtrace functions.
This function, if not NULL, will be called for certain error cases.
The DATA argument is passed to the function that calls this one.
The MSG argument is an error message. The ERRNUM argument, if
greater than 0, holds an errno value. The MSG buffer may become
invalid after this function returns.
As a special case, the ERRNUM argument will be passed as -1 if no
debug info can be found for the executable, but the function
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
MSG in this case will be something along the lines of "no debug
info". Similarly, ERRNUM will be passed as -1 if there is no
symbol table, but the function requires a symbol table (e.g.,
backtrace_syminfo). This may be used as a signal that some other
approach should be tried. */
typedef void (*backtrace_error_callback) (void *data, const char *msg,
int errnum);
/* Create state information for the backtrace routines. This must be
called before any of the other routines, and its return value must
be passed to all of the other routines. FILENAME is the path name
of the executable file; if it is NULL the library will try
system-specific path names. If not NULL, FILENAME must point to a
permanent buffer. If THREADED is non-zero the state may be
accessed by multiple threads simultaneously, and the library will
use appropriate locks (this requires that the library be configured
with --enable-backtrace-threads). If THREADED is zero the state
may only be accessed by one thread at a time. This returns a state
pointer on success, NULL on error. If an error occurs, this will
call the ERROR_CALLBACK routine. */
extern struct backtrace_state *backtrace_create_state (
const char *filename, int threaded,
backtrace_error_callback error_callback, void *data);
/* The type of the callback argument to the backtrace_full function.
DATA is the argument passed to backtrace_full. PC is the program
counter. FILENAME is the name of the file containing PC, or NULL
if not available. LINENO is the line number in FILENAME containing
PC, or 0 if not available. FUNCTION is the name of the function
containing PC, or NULL if not available. This should return 0 to
continuing tracing. The FILENAME and FUNCTION buffers may become
invalid after this function returns. */
typedef int (*backtrace_full_callback) (void *data, uintptr_t pc,
const char *filename, int lineno,
const char *function);
/* Get a full stack backtrace. SKIP is the number of frames to skip;
passing 0 will start the trace with the function calling
backtrace_full. DATA is passed to the callback routine. If any
call to CALLBACK returns a non-zero value, the stack backtrace
stops, and backtrace returns that value; this may be used to limit
the number of stack frames desired. If all calls to CALLBACK
return 0, backtrace returns 0. The backtrace_full function will
make at least one call to either CALLBACK or ERROR_CALLBACK. This
function requires debug info for the executable. */
extern int backtrace_full (struct backtrace_state *state, int skip,
backtrace_full_callback callback,
backtrace_error_callback error_callback,
void *data);
/* The type of the callback argument to the backtrace_simple function.
DATA is the argument passed to simple_backtrace. PC is the program
counter. This should return 0 to continue tracing. */
typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc);
/* Get a simple backtrace. SKIP is the number of frames to skip, as
in backtrace. DATA is passed to the callback routine. If any call
to CALLBACK returns a non-zero value, the stack backtrace stops,
and backtrace_simple returns that value. Otherwise
backtrace_simple returns 0. The backtrace_simple function will
make at least one call to either CALLBACK or ERROR_CALLBACK. This
function does not require any debug info for the executable. */
extern int backtrace_simple (struct backtrace_state *state, int skip,
backtrace_simple_callback callback,
backtrace_error_callback error_callback,
void *data);
/* Print the current backtrace in a user readable format to a FILE.
SKIP is the number of frames to skip, as in backtrace_full. Any
error messages are printed to stderr. This function requires debug
info for the executable. */
extern void backtrace_print (struct backtrace_state *state, int skip, FILE *);
/* Given PC, a program counter in the current program, call the
callback function with filename, line number, and function name
information. This will normally call the callback function exactly
once. However, if the PC happens to describe an inlined call, and
the debugging information contains the necessary information, then
this may call the callback function multiple times. This will make
at least one call to either CALLBACK or ERROR_CALLBACK. This
returns the first non-zero value returned by CALLBACK, or 0. */
extern int backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
backtrace_full_callback callback,
backtrace_error_callback error_callback,
void *data);
/* The type of the callback argument to backtrace_syminfo. DATA and
PC are the arguments passed to backtrace_syminfo. SYMNAME is the
name of the symbol for the corresponding code. SYMVAL is the
value. SYMNAME will be NULL if no error occurred but the symbol
could not be found. */
typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
const char *symname,
uintptr_t symval);
/* Given PC, a program counter in the current program, call the
callback information with the symbol name and value describing the
function in which PC may be found. This will call either CALLBACK
or ERROR_CALLBACK exactly once. This returns 1 on success, 0 on
failure. This function requires the symbol table but does not
require the debug info. Note that if the symbol table is present
but PC could not be found in the table, CALLBACK will be called
with a NULL SYMNAME argument. Returns 1 on success, 0 on
error. */
extern int backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
backtrace_syminfo_callback callback,
backtrace_error_callback error_callback,
void *data);
#ifdef __cplusplus
} /* End extern "C". */
#endif
#endif
/* config.h.in. Generated from configure.ac by autoheader. */
/* ELF size: 32 or 64 */
#undef BACKTRACE_ELF_SIZE
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if _Unwind_GetIPInfo is available. */
#undef HAVE_GETIPINFO
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the __sync functions */
#undef HAVE_SYNC_FUNCTIONS
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
This source diff could not be displayed because it is too large. You can view the blob instead.
# configure.ac -- Backtrace configure script.
# Copyright (C) 2012 Free Software Foundation, Inc.
# 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.
# (3) The name of the author may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
AC_PREREQ(2.64)
AC_INIT(package-unused, version-unused,, libbacktrace)
AC_CONFIG_SRCDIR(backtrace.h)
AC_CONFIG_HEADER(config.h)
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
libtool_VERSION=1:0:0
AC_SUBST(libtool_VERSION)
AM_INIT_AUTOMAKE([1.11.1 foreign no-dist no-define -Wall -Wno-portability])
AM_MAINTAINER_MODE
AC_ARG_WITH(target-subdir,
[ --with-target-subdir=SUBDIR Configuring in a subdirectory for target])
# We must force CC to /not/ be precious variables; otherwise
# the wrong, non-multilib-adjusted value will be used in multilibs.
# As a side effect, we have to subst CFLAGS ourselves.
m4_rename([_AC_ARG_VAR_PRECIOUS],[backtrace_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
AC_PROG_CC
m4_rename_force([backtrace_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AC_PROG_RANLIB
AC_PROG_AWK
case "$AWK" in
"") AC_MSG_ERROR([can't build without awk]) ;;
esac
LT_INIT([disable-shared])
AM_PROG_LIBTOOL
backtrace_supported=yes
if test -n "${with_target_subdir}"; then
# We are compiling a GCC library. We can assume that the unwind
# library exists.
AM_ENABLE_MULTILIB(, ..)
BACKTRACE_FILE="backtrace.lo simple.lo"
else
AC_CHECK_HEADER([unwind.h],
[AC_CHECK_FUNC([_Unwind_Backtrace],
[BACKTRACE_FILE="backtrace.lo simple.lo"],
[BACKTRACE_FILE="nounwind.lo"
backtrace_supported=no])],
[BACKTRACE_FILE="nounwind.lo"
backtrace_supported=no])
fi
AC_SUBST(BACKTRACE_FILE)
ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wold-style-definition \
-Wmissing-format-attribute -Wcast-qual],
[WARN_FLAGS])
if test "x$GCC" = "xyes"; then
WARN_FLAGS="$WARN_FLAGS -Werror"
fi
AC_SUBST(WARN_FLAGS)
GCC_CHECK_UNWIND_GETIPINFO
# When building as a target library, shared libraries may want to link
# this in. We don't want to provide another shared library to
# complicate dependencies. Instead, we just compile with -fPIC.
PIC_FLAG=
if test -n "${with_target_subdir}"; then
PIC_FLAG=-fPIC
fi
AC_SUBST(PIC_FLAG)
# Test for __sync support.
AC_CACHE_CHECK([__sync extensions],
[libbacktrace_cv_sys_sync],
[if test -n "${with_target_subdir}"; then
libbacktrace_cv_sys_sync=yes
else
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([int i;],
[__sync_bool_compare_and_swap (&i, i, i);
__sync_lock_test_and_set (&i, 1);
__sync_lock_release (&i);])],
[libbacktrace_cv_sys_sync=yes],
[libbacktrace_cv_sys_sync=no])
fi])
BACKTRACE_SUPPORTS_THREADS=0
if test "$libbacktrace_cv_sys_sync" = "yes"; then
BACKTRACE_SUPPORTS_THREADS=1
AC_DEFINE([HAVE_SYNC_FUNCTIONS], 1,
[Define to 1 if you have the __sync functions])
fi
AC_SUBST(BACKTRACE_SUPPORTS_THREADS)
# The library needs to be able to read the executable itself. Compile
# a file to determine the executable format. The awk script
# filetype.awk prints out the file type.
AC_CACHE_CHECK([output filetype],
[libbacktrace_cv_sys_filetype],
[filetype=
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([int i;], [int j;])],
[filetype=`${AWK} -f $srcdir/filetype.awk conftest.$ac_objext`],
[AC_MSG_FAILURE([compiler failed])])
libbacktrace_cv_sys_filetype=$filetype])
# Match the file type to decide what files to compile.
FORMAT_FILE=
case "$libbacktrace_cv_sys_filetype" in
elf*) FORMAT_FILE="elf.lo" ;;
*) AC_MSG_WARN([could not determine output file type])
FORMAT_FILE="unknown.lo"
backtrace_supported=no
;;
esac
AC_SUBST(FORMAT_FILE)
# ELF defines.
elfsize=
case "$libbacktrace_cv_sys_filetype" in
elf32) elfsize=32 ;;
elf64) elfsize=64 ;;
esac
AC_DEFINE_UNQUOTED([BACKTRACE_ELF_SIZE], [$elfsize], [ELF size: 32 or 64])
BACKTRACE_SUPPORTED=0
if test "$backtrace_supported" = "yes"; then
BACKTRACE_SUPPORTED=1
fi
AC_SUBST(BACKTRACE_SUPPORTED)
AC_CHECK_HEADERS(sys/mman.h)
if test "$ac_cv_header_sys_mman_h" = "no"; then
have_mmap=no
else
if test -n "${with_target_subdir}"; then
# When built as a GCC target library, we can't do a link test. We
# simply assume that if we have mman.h, we have mmap.
have_mmap=yes
else
AC_CHECK_FUNC(mmap, [have_mmap=yes], [have_mmap=no])
fi
fi
if test "$have_mmap" = "no"; then
VIEW_FILE=read.lo
ALLOC_FILE=alloc.lo
else
VIEW_FILE=mmapio.lo
AC_PREPROC_IFELSE([
#include <sys/mman.h>
#if !defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
#error no MAP_ANONYMOUS
#endif
], [ALLOC_FILE=mmap.lo], [ALLOC_FILE=alloc.lo])
fi
AC_SUBST(VIEW_FILE)
AC_SUBST(ALLOC_FILE)
BACKTRACE_USES_MALLOC=0
if test "$ALLOC_FILE" = "alloc.lo"; then
BACKTRACE_USES_MALLOC=1
fi
AC_SUBST(BACKTRACE_USES_MALLOC)
AC_CACHE_CHECK([whether tests can run],
[libbacktrace_cv_sys_native],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
[libbacktrace_cv_sys_native=yes],
[libbacktrace_cv_sys_native=no],
[libbacktrace_cv_sys_native=no])])
AM_CONDITIONAL(NATIVE, test "$libbacktrace_cv_sys_native" = "yes")
if test "${multilib}" = "yes"; then
multilib_arg="--enable-multilib"
else
multilib_arg=
fi
AC_CONFIG_FILES(Makefile backtrace-supported.h)
# We need multilib support, but only if configuring for the target.
AC_CONFIG_COMMANDS([default],
[if test -n "$CONFIG_FILES"; then
if test -n "${with_target_subdir}"; then
# Multilibs need MULTISUBDIR defined correctly in certain makefiles so
# that multilib installs will end up installed in the correct place.
# The testsuite needs it for multilib-aware ABI baseline files.
# To work around this not being passed down from config-ml.in ->
# srcdir/Makefile.am -> srcdir/{src,libsupc++,...}/Makefile.am, manually
# append it here. Only modify Makefiles that have just been created.
#
# Also, get rid of this simulated-VPATH thing that automake does.
cat > vpsed << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
for i in $SUBDIRS; do
case $CONFIG_FILES in
*${i}/Makefile*)
#echo "Adding MULTISUBDIR to $i/Makefile"
sed -f vpsed $i/Makefile > tmp
grep '^MULTISUBDIR =' Makefile >> tmp
mv tmp $i/Makefile
;;
esac
done
rm vpsed
fi
fi
],
[
# Variables needed in config.status (file generation) which aren't already
# passed by autoconf.
SUBDIRS="$SUBDIRS"
])
AC_OUTPUT
/* fileline.c -- Get file and line number information in a backtrace.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "backtrace.h"
#include "internal.h"
/* Initialize the fileline information from the executable. Returns 1
on success, 0 on failure. */
static int
fileline_initialize (struct backtrace_state *state,
backtrace_error_callback error_callback, void *data)
{
int failed;
fileline fileline_fn;
int descriptor;
failed = state->fileline_initialization_failed;
if (state->threaded)
{
/* Use __sync_bool_compare_and_swap to do an atomic load. */
while (!__sync_bool_compare_and_swap
(&state->fileline_initialization_failed, failed, failed))
failed = state->fileline_initialization_failed;
}
if (failed)
{
error_callback (data, "failed to read executable information", 0);
return 0;
}
fileline_fn = state->fileline_fn;
if (state->threaded)
{
while (!__sync_bool_compare_and_swap (&state->fileline_fn, fileline_fn,
fileline_fn))
fileline_fn = state->fileline_fn;
}
if (fileline_fn != NULL)
return 1;
/* We have not initialized the information. Do it now. */
if (state->filename != NULL)
descriptor = backtrace_open (state->filename, error_callback, data);
else
descriptor = backtrace_open ("/proc/self/exe", error_callback, data);
if (descriptor < 0)
failed = 1;
if (!failed)
{
if (!backtrace_initialize (state, descriptor, error_callback, data,
&fileline_fn))
failed = 1;
}
if (failed)
{
if (!state->threaded)
state->fileline_initialization_failed = 1;
else
__sync_bool_compare_and_swap (&state->fileline_initialization_failed,
0, failed);
return 0;
}
if (!state->threaded)
state->fileline_fn = fileline_fn;
else
{
__sync_bool_compare_and_swap (&state->fileline_fn, NULL, fileline_fn);
/* At this point we know that state->fileline_fn is not NULL.
Either we stored our value, or some other thread stored its
value. If some other thread stored its value, we leak the
one we just initialized. Either way, state->fileline_fn is
initialized. The compare_and_swap is a full memory barrier,
so we should have full access to that value even if it was
created by another thread. */
}
return 1;
}
/* Given a PC, find the file name, line number, and function name. */
int
backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
backtrace_full_callback callback,
backtrace_error_callback error_callback, void *data)
{
if (!fileline_initialize (state, error_callback, data))
return 0;
if (state->fileline_initialization_failed)
return 0;
return state->fileline_fn (state, pc, callback, error_callback, data);
}
/* Given a PC, find the symbol for it, and its value. */
int
backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
backtrace_syminfo_callback callback,
backtrace_error_callback error_callback, void *data)
{
if (!fileline_initialize (state, error_callback, data))
return 0;
if (state->fileline_initialization_failed)
return 0;
state->syminfo_fn (state, pc, callback, error_callback, data);
return 1;
}
# An awk script to determine the type of a file.
/\177ELF\001/ { if (NR == 1) { print "elf32"; exit } }
/\177ELF\002/ { if (NR == 1) { print "elf64"; exit } }
/* internal.h -- Internal header file for stack backtrace library.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */
#ifndef BACKTRACE_INTERNAL_H
#define BACKTRACE_INTERNAL_H
/* We assume that <sys/types.h> and "backtrace.h" have already been
included. */
#ifndef GCC_VERSION
# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#endif
#if (GCC_VERSION < 2007)
# define __attribute__(x)
#endif
#ifndef ATTRIBUTE_UNUSED
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#endif
#ifndef ATTRIBUTE_MALLOC
# if (GCC_VERSION >= 2096)
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
# else
# define ATTRIBUTE_MALLOC
# endif
#endif
#ifndef HAVE_SYNC_FUNCTIONS
/* Define out the sync functions. These should never be called if
they are not available. */
#define __sync_bool_compare_and_swap(A, B, C) (abort(), 1)
#define __sync_lock_test_and_set(A, B) (abort(), 0)
#define __sync_lock_release(A) abort()
#endif /* !defined(HAVE_SYNC_FUNCTIONS) */
/* The type of the function that collects file/line information. This
is like backtrace_pcinfo. */
typedef int (*fileline) (struct backtrace_state *state, uintptr_t pc,
backtrace_full_callback callback,
backtrace_error_callback error_callback, void *data);
/* The type of the function that collects symbol information. This is
like backtrace_syminfo. */
typedef void (*syminfo) (struct backtrace_state *state, uintptr_t pc,
backtrace_syminfo_callback callback,
backtrace_error_callback error_callback, void *data);
/* What the backtrace state pointer points to. */
struct backtrace_state
{
/* The name of the executable. */
const char *filename;
/* Non-zero if threaded. */
int threaded;
/* The master lock for fileline_fn, fileline_data, syminfo_fn,
syminfo_data, fileline_initialization_failed and everything the
data pointers point to. */
void *lock;
/* The function that returns file/line information. */
fileline fileline_fn;
/* The data to pass to FILELINE_FN. */
void *fileline_data;
/* The function that returns symbol information. */
syminfo syminfo_fn;
/* The data to pass to SYMINFO_FN. */
void *syminfo_data;
/* Whether initializing the file/line information failed. */
int fileline_initialization_failed;
/* The lock for the freelist. */
int lock_alloc;
/* The freelist when using mmap. */
struct backtrace_freelist_struct *freelist;
};
/* Open a file for reading. Returns -1 on error. */
extern int backtrace_open (const char *filename,
backtrace_error_callback error_callback,
void *data);
/* A view of the contents of a file. This supports mmap when
available. A view will remain in memory even after backtrace_close
is called on the file descriptor from which the view was
obtained. */
struct backtrace_view
{
/* The data that the caller requested. */
const void *data;
/* The base of the view. */
void *base;
/* The total length of the view. */
size_t len;
};
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. Store the
result in *VIEW. Returns 1 on success, 0 on error. */
extern int backtrace_get_view (struct backtrace_state *state, int descriptor,
off_t offset, size_t size,
backtrace_error_callback error_callback,
void *data, struct backtrace_view *view);
/* Release a view created by backtrace_get_view. */
extern void backtrace_release_view (struct backtrace_state *state,
struct backtrace_view *view,
backtrace_error_callback error_callback,
void *data);
/* Close a file opened by backtrace_open. Returns 1 on success, 0 on
error. */
extern int backtrace_close (int descriptor,
backtrace_error_callback error_callback,
void *data);
/* Allocate memory. This is like malloc. */
extern void *backtrace_alloc (struct backtrace_state *state, size_t size,
backtrace_error_callback error_callback,
void *data) ATTRIBUTE_MALLOC;
/* Free memory allocated by backtrace_alloc. */
extern void backtrace_free (struct backtrace_state *state, void *mem,
size_t size,
backtrace_error_callback error_callback,
void *data);
/* A growable vector of some struct. This is used for more efficient
allocation when we don't know the final size of some group of data
that we want to represent as an array. */
struct backtrace_vector
{
/* The base of the vector. */
void *base;
/* The number of bytes in the vector. */
size_t size;
/* The number of bytes available at the current allocation. */
size_t alc;
};
/* Grow VEC by SIZE bytes. Return a pointer to the newly allocated
bytes. Note that this may move the entire vector to a new memory
location. Returns NULL on failure. */
extern void *backtrace_vector_grow (struct backtrace_state *state, size_t size,
backtrace_error_callback error_callback,
void *data,
struct backtrace_vector *vec);
/* Finish the current allocation on VEC. Prepare to start a new
allocation. The finished allocation will never be freed. */
extern void backtrace_vector_finish (struct backtrace_state *state,
struct backtrace_vector *vec);
/* Release any extra space allocated for VEC. Returns 1 on success, 0
on failure. */
extern int backtrace_vector_release (struct backtrace_state *state,
struct backtrace_vector *vec,
backtrace_error_callback error_callback,
void *data);
/* Read initial debug data from a descriptor, and set the
fileline_data, syminfo_fn, and syminfo_data fields of STATE.
Return the fileln_fn field in *FILELN_FN--this is done this way so
that the synchronization code is only implemented once. This is
called after the descriptor has first been opened. It will close
the descriptor if it is no longer needed. Returns 1 on success, 0
on error. There will be multiple implementations of this function,
for different file formats. Each system will compile the
appropriate one. */
extern int backtrace_initialize (struct backtrace_state *state,
int descriptor,
backtrace_error_callback error_callback,
void *data,
fileline *fileline_fn);
/* Prepare to read file/line information from DWARF debug data. */
extern int backtrace_dwarf_initialize (struct backtrace_state *state,
const unsigned char* dwarf_info,
size_t dwarf_info_size,
const unsigned char *dwarf_line,
size_t dwarf_line_size,
const unsigned char *dwarf_abbrev,
size_t dwarf_abbrev_size,
const unsigned char *dwarf_ranges,
size_t dwarf_range_size,
const unsigned char *dwarf_str,
size_t dwarf_str_size,
int is_bigendian,
backtrace_error_callback error_callback,
void *data, fileline *fileline_fn);
#endif
/* mmap.c -- Memory allocation with mmap.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include "backtrace.h"
#include "internal.h"
/* Memory allocation on systems that provide anonymous mmap. This
permits the backtrace functions to be invoked from a signal
handler, assuming that mmap is async-signal safe. */
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
/* A list of free memory blocks. */
struct backtrace_freelist_struct
{
/* Next on list. */
struct backtrace_freelist_struct *next;
/* Size of this block, including this structure. */
size_t size;
};
/* Free memory allocated by backtrace_alloc. */
static void
backtrace_free_locked (struct backtrace_state *state, void *addr, size_t size)
{
/* Just leak small blocks. We don't have to be perfect. */
if (size >= sizeof (struct backtrace_freelist_struct))
{
struct backtrace_freelist_struct *p;
p = (struct backtrace_freelist_struct *) addr;
p->next = state->freelist;
p->size = size;
state->freelist = p;
}
}
/* Allocate memory like malloc. */
void *
backtrace_alloc (struct backtrace_state *state,
size_t size, backtrace_error_callback error_callback,
void *data)
{
void *ret;
struct backtrace_freelist_struct **pp;
size_t pagesize;
size_t asksize;
void *page;
ret = NULL;
/* If we can acquire the lock, then see if there is space on the
free list. If we can't acquire the lock, drop straight into
using mmap. __sync_lock_test_and_set returns the old state of
the lock, so we have acquired it if it returns 0. */
if (!__sync_lock_test_and_set (&state->lock_alloc, 1))
{
for (pp = &state->freelist; *pp != NULL; pp = &(*pp)->next)
{
if ((*pp)->size >= size)
{
struct backtrace_freelist_struct *p;
p = *pp;
*pp = p->next;
/* Round for alignment; we assume that no type we care about
is more than 8 bytes. */
size = (size + 7) & ~ (size_t) 7;
if (size < p->size)
backtrace_free_locked (state, (char *) p + size,
p->size - size);
ret = (void *) p;
break;
}
}
__sync_lock_release (&state->lock_alloc);
}
if (ret == NULL)
{
/* Allocate a new page. */
pagesize = getpagesize ();
asksize = (size + pagesize - 1) & ~ (pagesize - 1);
page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (page == NULL)
error_callback (data, "mmap", errno);
else
{
size = (size + 7) & ~ (size_t) 7;
if (size < asksize)
backtrace_free (state, (char *) page + size, asksize - size,
error_callback, data);
ret = page;
}
}
return ret;
}
/* Free memory allocated by backtrace_alloc. */
void
backtrace_free (struct backtrace_state *state, void *addr, size_t size,
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED)
{
/* If we can acquire the lock, add the new space to the free list.
If we can't acquire the lock, just leak the memory.
__sync_lock_test_and_set returns the old state of the lock, so we
have acquired it if it returns 0. */
if (!__sync_lock_test_and_set (&state->lock_alloc, 1))
{
backtrace_free_locked (state, addr, size);
__sync_lock_release (&state->lock_alloc);
}
}
/* Grow VEC by SIZE bytes. */
void *
backtrace_vector_grow (struct backtrace_state *state,size_t size,
backtrace_error_callback error_callback,
void *data, struct backtrace_vector *vec)
{
void *ret;
if (size > vec->alc)
{
size_t pagesize;
size_t alc;
void *base;
pagesize = getpagesize ();
alc = vec->size + size;
if (vec->size == 0)
alc = 16 * size;
else if (alc < pagesize)
{
alc *= 2;
if (alc > pagesize)
alc = pagesize;
}
else
alc = (alc + pagesize - 1) & ~ (pagesize - 1);
base = backtrace_alloc (state, alc, error_callback, data);
if (base == NULL)
return NULL;
if (vec->base != NULL)
{
memcpy (base, vec->base, vec->size);
backtrace_free (state, vec->base, vec->alc, error_callback, data);
}
vec->base = base;
vec->alc = alc - vec->size;
}
ret = (char *) vec->base + vec->size;
vec->size += size;
vec->alc -= size;
return ret;
}
/* Finish the current allocation on VEC. */
void
backtrace_vector_finish (struct backtrace_state *state ATTRIBUTE_UNUSED,
struct backtrace_vector *vec)
{
vec->base = (char *) vec->base + vec->size;
vec->size = 0;
}
/* Release any extra space allocated for VEC. */
int
backtrace_vector_release (struct backtrace_state *state,
struct backtrace_vector *vec,
backtrace_error_callback error_callback,
void *data)
{
backtrace_free (state, (char *) vec->base + vec->size, vec->alc,
error_callback, data);
vec->alc = 0;
return 1;
}
/* mmapio.c -- File views using mmap.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */
#define _GNU_SOURCE
#include "config.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include "backtrace.h"
#include "internal.h"
/* This file implements file views and memory allocation when mmap is
available. */
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. */
int
backtrace_get_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
int descriptor, off_t offset, size_t size,
backtrace_error_callback error_callback,
void *data, struct backtrace_view *view)
{
size_t pagesize;
unsigned int inpage;
off_t pageoff;
void *map;
pagesize = getpagesize ();
inpage = offset % pagesize;
pageoff = offset - inpage;
size += inpage;
size = (size + (pagesize - 1)) & ~ (pagesize - 1);
map = mmap (NULL, size, PROT_READ, MAP_PRIVATE, descriptor, pageoff);
if (map == MAP_FAILED)
{
error_callback (data, "mmap", errno);
return 0;
}
view->data = (char *) map + inpage;
view->base = map;
view->len = size;
return 1;
}
/* Release a view read by backtrace_get_view. */
void
backtrace_release_view (struct backtrace_state *state ATTRIBUTE_UNUSED,
struct backtrace_view *view,
backtrace_error_callback error_callback,
void *data)
{
union {
const void *cv;
void *v;
} const_cast;
const_cast.cv = view->base;
if (munmap (const_cast.v, view->len) < 0)
error_callback (data, "munmap", errno);
}
/* backtrace.c -- Entry point for stack backtrace library.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <sys/types.h>
#include "backtrace.h"
#include "internal.h"
/* This source file is compiled if the unwind library is not
available. */
int
backtrace (int skip ATTRIBUTE_UNUSED,
backtrace_full_callback callback ATTRIBUTE_UNUSED,
backtrace_error_callback error_callback, void *data)
{
error_callback (data,
"no stack trace because unwind library not available",
0);
return 0;
}
int
backtrace_simple (int skip ATTRIBUTE_UNUSED,
backtrace_simple_callback callback ATTRIBUTE_UNUSED,
backtrace_error_callback error_callback, void *data)
{
error_callback (data,
"no stack trace because unwind library not available",
0);
return 0;
}
/* posix.c -- POSIX file I/O routines for the backtrace library.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "backtrace.h"
#include "internal.h"
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
#ifndef FD_CLOEXEC
#define FD_CLOEXEC 1
#endif
/* Open a file for reading. */
int
backtrace_open (const char *filename, backtrace_error_callback error_callback,
void *data)
{
int descriptor;
descriptor = open (filename, O_RDONLY | O_CLOEXEC);
if (descriptor < 0)
{
error_callback (data, filename, errno);
return -1;
}
/* Set FD_CLOEXEC just in case the kernel does not support
O_CLOEXEC. It doesn't matter if this fails for some reason.
FIXME: At some point it should be safe to only do this if
O_CLOEXEC == 0. */
fcntl (descriptor, F_SETFD, FD_CLOEXEC);
return descriptor;
}
/* Close DESCRIPTOR. */
int
backtrace_close (int descriptor, backtrace_error_callback error_callback,
void *data)
{
if (close (descriptor) < 0)
{
error_callback (data, "close", errno);
return 0;
}
return 1;
}
/* print.c -- Print the current backtrace.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "backtrace.h"
#include "internal.h"
/* Passed to callbacks. */
struct print_data
{
struct backtrace_state *state;
FILE *f;
};
/* Print one level of a backtrace. */
static int
print_callback (void *data, uintptr_t pc, const char *filename, int lineno,
const char *function)
{
struct print_data *pdata = (struct print_data *) data;
fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n",
(unsigned long) pc,
function == NULL ? "???" : function,
filename == NULL ? "???" : filename,
lineno);
return 0;
}
/* Print errors to stderr. */
static void
error_callback (void *data, const char *msg, int errnum)
{
struct print_data *pdata = (struct print_data *) data;
const char *name;
name = pdata->state->filename;
if (name == NULL)
name = "/proc/self/exe";
fprintf (stderr, "%s: libbacktrace: %s", name, msg);
if (errnum > 0)
fprintf (stderr, ": %s", strerror (errnum));
fputc ('\n', stderr);
}
/* Print a backtrace. */
void
backtrace_print (struct backtrace_state *state, int skip, FILE *f)
{
struct print_data data;
data.state = state;
data.f = f;
backtrace_full (state, skip + 1, print_callback, error_callback,
(void *) &data);
}
/* read.c -- File views without mmap.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include "backtrace.h"
#include "internal.h"
/* This file implements file views when mmap is not available. */
/* Create a view of SIZE bytes from DESCRIPTOR at OFFSET. */
int
backtrace_get_view (struct backtrace_state *state, int descriptor,
off_t offset, size_t size,
backtrace_error_callback error_callback,
void *data, struct backtrace_view *view)
{
ssize_t got;
if (lseek (descriptor, offset, SEEK_SET) < 0)
{
error_callback (data, "lseek", errno);
return 0;
}
view->base = backtrace_alloc (state, size, error_callback, data);
if (view->base == NULL)
return 0;
view->data = view->base;
view->len = size;
got = read (descriptor, view->base, size);
if (got < 0)
{
error_callback (data, "read", errno);
free (view->base);
return 0;
}
if ((size_t) got < size)
{
error_callback (data, "file too short", 0);
free (view->base);
return 0;
}
return 1;
}
/* Release a view read by backtrace_get_view. */
void
backtrace_release_view (struct backtrace_state *state,
struct backtrace_view *view,
backtrace_error_callback error_callback,
void *data)
{
backtrace_free (state, view->base, view->len, error_callback, data);
view->data = NULL;
view->base = NULL;
}
/* simple.c -- The backtrace_simple function.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include "unwind.h"
#include "backtrace.h"
/* The simple_backtrace routine. */
/* Data passed through _Unwind_Backtrace. */
struct backtrace_simple_data
{
/* Number of frames to skip. */
int skip;
/* Library state. */
struct backtrace_state *state;
/* Callback routine. */
backtrace_simple_callback callback;
/* Error callback routine. */
backtrace_error_callback error_callback;
/* Data to pass to callback routine. */
void *data;
/* Value to return from backtrace. */
int ret;
};
/* Unwind library callback routine. This is passd to
_Unwind_Backtrace. */
static _Unwind_Reason_Code
simple_unwind (struct _Unwind_Context *context, void *vdata)
{
struct backtrace_simple_data *bdata = (struct backtrace_simple_data *) vdata;
uintptr_t pc;
int ip_before_insn = 0;
#ifdef HAVE_GETIPINFO
pc = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
pc = _Unwind_GetIP (context);
#endif
if (bdata->skip > 0)
{
--bdata->skip;
return _URC_NO_REASON;
}
if (!ip_before_insn)
--pc;
bdata->ret = bdata->callback (bdata->data, pc);
if (bdata->ret != 0)
return _URC_END_OF_STACK;
return _URC_NO_REASON;
}
/* Get a simple stack backtrace. */
int
backtrace_simple (struct backtrace_state *state, int skip,
backtrace_simple_callback callback,
backtrace_error_callback error_callback, void *data)
{
struct backtrace_simple_data bdata;
bdata.skip = skip + 1;
bdata.state = state;
bdata.callback = callback;
bdata.error_callback = error_callback;
bdata.data = data;
bdata.ret = 0;
_Unwind_Backtrace (simple_unwind, &bdata);
return bdata.ret;
}
/* state.c -- Create the backtrace state.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <string.h>
#include <sys/types.h>
#include "backtrace.h"
#include "backtrace-supported.h"
#include "internal.h"
/* Create the backtrace state. This will then be passed to all the
other routines. */
struct backtrace_state *
backtrace_create_state (const char *filename, int threaded,
backtrace_error_callback error_callback,
void *data)
{
struct backtrace_state init_state;
struct backtrace_state *state;
#ifndef HAVE_SYNC_FUNCTIONS
if (threaded)
{
error_callback (data, "backtrace library does not support threads", 0);
return NULL;
}
#endif
memset (&init_state, 0, sizeof init_state);
init_state.filename = filename;
init_state.threaded = threaded;
state = ((struct backtrace_state *)
backtrace_alloc (&init_state, sizeof *state, error_callback, data));
if (state == NULL)
return NULL;
*state = init_state;
return state;
}
/* unknown.c -- used when backtrace configury does not know file format.
Copyright (C) 2012 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "config.h"
#include <sys/types.h>
#include "backtrace.h"
#include "internal.h"
/* A trivial routine that always fails to find fileline data. */
static int
unknown_fileline (void *fileline_data ATTRIBUTE_UNUSED,
uintptr_t pc, backtrace_full_callback callback,
backtrace_error_callback ATTRIBUTE_UNUSED,
void *data)
{
return callback (data, pc, NULL, 0, NULL);
}
/* Initialize the backtrace data when we don't know how to read the
debug info. */
int
backtrace_initialize (int descriptor ATTRIBUTE_UNUSED,
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED, fileline *fileline_fn,
void **fileline_data)
{
*fileline_fn = unknown_fileline;
*fileline_data = NULL;
return 1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment