mirror of
https://github.com/wolfpld/tracy
synced 2025-04-29 04:23:51 +00:00
Add modified libbacktrace.
https://github.com/ianlancetaylor/libbacktrace 5a99ff7fed66b8ea8f09c9805c138524a7035ece
This commit is contained in:
parent
d4e9baa0d9
commit
0ce3dfaba7
29
libbacktrace/LICENSE
Normal file
29
libbacktrace/LICENSE
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (C) 2012-2016 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.
|
163
libbacktrace/alloc.cpp
Normal file
163
libbacktrace/alloc.cpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/* alloc.c -- Memory allocation without mmap.
|
||||||
|
Copyright (C) 2012-2018 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 "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#include "../client/tracy_rpmalloc.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* 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. If ERROR_CALLBACK is NULL, don't
|
||||||
|
report an error. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
|
size_t size, backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
ret = rpmalloc (size);
|
||||||
|
if (ret == NULL)
|
||||||
|
{
|
||||||
|
if (error_callback)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
rpfree (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 = rprealloc (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,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
/* With this allocator we call realloc in backtrace_vector_grow,
|
||||||
|
which means we can't easily reuse the memory here. So just
|
||||||
|
release it. */
|
||||||
|
if (!backtrace_vector_release (state, vec, error_callback, data))
|
||||||
|
return NULL;
|
||||||
|
ret = vec->base;
|
||||||
|
vec->base = NULL;
|
||||||
|
vec->size = 0;
|
||||||
|
vec->alc = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 = rprealloc (vec->base, vec->size);
|
||||||
|
if (vec->base == NULL)
|
||||||
|
{
|
||||||
|
error_callback (data, "realloc", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
vec->alc = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
179
libbacktrace/backtrace.hpp
Normal file
179
libbacktrace/backtrace.hpp
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/* backtrace.h -- Public header file for stack backtrace library.
|
||||||
|
Copyright (C) 2012-2018 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>
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* 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 atomic operations. 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 and SYMSIZE is the size of the symbol. 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,
|
||||||
|
uintptr_t symsize);
|
||||||
|
|
||||||
|
/* Given ADDR, an address or program counter in the current program,
|
||||||
|
call the callback information with the symbol name and value
|
||||||
|
describing the function or variable in which ADDR 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 ADDR 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 addr,
|
||||||
|
backtrace_syminfo_callback callback,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
13
libbacktrace/config.h
Normal file
13
libbacktrace/config.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <limits.h>
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
# define BACKTRACE_ELF_SIZE 64
|
||||||
|
#else
|
||||||
|
# define BACKTRACE_ELF_SIZE 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HAVE_DLFCN_H
|
||||||
|
#define HAVE_FCNTL
|
||||||
|
#define HAVE_INTTYPES_H
|
||||||
|
#define HAVE_LSTAT
|
||||||
|
#define HAVE_READLINK
|
||||||
|
#define HAVE_DL_ITERATE_PHDR
|
3061
libbacktrace/dwarf.cpp
Normal file
3061
libbacktrace/dwarf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3264
libbacktrace/elf.cpp
Normal file
3264
libbacktrace/elf.cpp
Normal file
File diff suppressed because it is too large
Load Diff
189
libbacktrace/fileline.cpp
Normal file
189
libbacktrace/fileline.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/* fileline.c -- Get file and line number information in a backtrace.
|
||||||
|
Copyright (C) 2012-2018 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 <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#ifndef HAVE_GETEXECNAME
|
||||||
|
#define getexecname() NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* 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 pass;
|
||||||
|
int called_error_callback;
|
||||||
|
int descriptor;
|
||||||
|
const char *filename;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
failed = state->fileline_initialization_failed;
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
error_callback (data, "failed to read executable information", -1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileline_fn = state->fileline_fn;
|
||||||
|
if (fileline_fn != NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* We have not initialized the information. Do it now. */
|
||||||
|
|
||||||
|
descriptor = -1;
|
||||||
|
called_error_callback = 0;
|
||||||
|
for (pass = 0; pass < 5; ++pass)
|
||||||
|
{
|
||||||
|
int does_not_exist;
|
||||||
|
|
||||||
|
switch (pass)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
filename = state->filename;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
filename = getexecname ();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
filename = "/proc/self/exe";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
filename = "/proc/curproc/file";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
|
||||||
|
(long) getpid ());
|
||||||
|
filename = buf;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
descriptor = backtrace_open (filename, error_callback, data,
|
||||||
|
&does_not_exist);
|
||||||
|
if (descriptor < 0 && !does_not_exist)
|
||||||
|
{
|
||||||
|
called_error_callback = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (descriptor >= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (descriptor < 0)
|
||||||
|
{
|
||||||
|
if (!called_error_callback)
|
||||||
|
{
|
||||||
|
if (state->filename != NULL)
|
||||||
|
error_callback (data, state->filename, ENOENT);
|
||||||
|
else
|
||||||
|
error_callback (data,
|
||||||
|
"libbacktrace could not find executable to open",
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failed)
|
||||||
|
{
|
||||||
|
if (!backtrace_initialize (state, filename, descriptor, error_callback,
|
||||||
|
data, &fileline_fn))
|
||||||
|
failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
state->fileline_initialization_failed = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->fileline_fn = fileline_fn;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
264
libbacktrace/internal.hpp
Normal file
264
libbacktrace/internal.hpp
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/* internal.h -- Internal header file for stack backtrace library.
|
||||||
|
Copyright (C) 2012-2018 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 TRACY_BACKTRACE_INTERNAL_H
|
||||||
|
#define TRACY_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
|
||||||
|
|
||||||
|
/* 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()
|
||||||
|
|
||||||
|
/* We have neither the sync nor the atomic functions. These will
|
||||||
|
never be called. */
|
||||||
|
|
||||||
|
#define backtrace_atomic_load_pointer(p) (abort(), (void *) NULL)
|
||||||
|
#define backtrace_atomic_load_int(p) (abort(), 0)
|
||||||
|
#define backtrace_atomic_store_pointer(p, v) abort()
|
||||||
|
#define backtrace_atomic_store_size_t(p, v) abort()
|
||||||
|
#define backtrace_atomic_store_int(p, v) abort()
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* 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. If DOES_NOT_EXIST
|
||||||
|
is not NULL, *DOES_NOT_EXIST will be set to 0 normally and set to 1
|
||||||
|
if the file does not exist. If the file does not exist and
|
||||||
|
DOES_NOT_EXIST is not NULL, the function will return -1 and will
|
||||||
|
not call ERROR_CALLBACK. On other errors, or if DOES_NOT_EXIST is
|
||||||
|
NULL, the function will call ERROR_CALLBACK before returning. */
|
||||||
|
extern int backtrace_open (const char *filename,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
int *does_not_exist);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* Sort without using memory. */
|
||||||
|
|
||||||
|
extern void backtrace_qsort (void *base, size_t count, size_t size,
|
||||||
|
int (*compar) (const void *, const void *));
|
||||||
|
|
||||||
|
/* Allocate memory. This is like malloc. If ERROR_CALLBACK is NULL,
|
||||||
|
this does not report an error, it just returns NULL. */
|
||||||
|
|
||||||
|
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. If ERROR_CALLBACK is
|
||||||
|
NULL, this does not report an error. */
|
||||||
|
|
||||||
|
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. Returns
|
||||||
|
a pointer to the base of the finished entries, or NULL on
|
||||||
|
failure. */
|
||||||
|
|
||||||
|
extern void* backtrace_vector_finish (struct backtrace_state *state,
|
||||||
|
struct backtrace_vector *vec,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* Release any extra space allocated for VEC. This may change
|
||||||
|
VEC->base. 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,
|
||||||
|
const char *filename,
|
||||||
|
int descriptor,
|
||||||
|
backtrace_error_callback error_callback,
|
||||||
|
void *data,
|
||||||
|
fileline *fileline_fn);
|
||||||
|
|
||||||
|
/* Add file/line information for a DWARF module. */
|
||||||
|
|
||||||
|
extern int backtrace_dwarf_add (struct backtrace_state *state,
|
||||||
|
uintptr_t base_address,
|
||||||
|
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
|
99
libbacktrace/mmapio.cpp
Normal file
99
libbacktrace/mmapio.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/* mmapio.c -- File views using mmap.
|
||||||
|
Copyright (C) 2012-2018 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/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#ifndef MAP_FAILED
|
||||||
|
#define MAP_FAILED ((void *)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
if (munmap (view->base, view->len) < 0)
|
||||||
|
error_callback (data, "munmap", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
105
libbacktrace/posix.cpp
Normal file
105
libbacktrace/posix.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* posix.c -- POSIX file I/O routines for the backtrace library.
|
||||||
|
Copyright (C) 2012-2018 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.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Open a file for reading. */
|
||||||
|
|
||||||
|
int
|
||||||
|
backtrace_open (const char *filename, backtrace_error_callback error_callback,
|
||||||
|
void *data, int *does_not_exist)
|
||||||
|
{
|
||||||
|
int descriptor;
|
||||||
|
|
||||||
|
if (does_not_exist != NULL)
|
||||||
|
*does_not_exist = 0;
|
||||||
|
|
||||||
|
descriptor = open (filename, (int) (O_RDONLY | O_BINARY | O_CLOEXEC));
|
||||||
|
if (descriptor < 0)
|
||||||
|
{
|
||||||
|
if (does_not_exist != NULL && errno == ENOENT)
|
||||||
|
*does_not_exist = 1;
|
||||||
|
else
|
||||||
|
error_callback (data, filename, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_FCNTL
|
||||||
|
/* 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);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
113
libbacktrace/sort.cpp
Normal file
113
libbacktrace/sort.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/* sort.c -- Sort without allocating memory
|
||||||
|
Copyright (C) 2012-2018 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 <stddef.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "backtrace.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* The GNU glibc version of qsort allocates memory, which we must not
|
||||||
|
do if we are invoked by a signal handler. So provide our own
|
||||||
|
sort. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
swap (char *a, char *b, size_t size)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++, a++, b++)
|
||||||
|
{
|
||||||
|
char t;
|
||||||
|
|
||||||
|
t = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
backtrace_qsort (void *basearg, size_t count, size_t size,
|
||||||
|
int (*compar) (const void *, const void *))
|
||||||
|
{
|
||||||
|
char *base = (char *) basearg;
|
||||||
|
size_t i;
|
||||||
|
size_t mid;
|
||||||
|
|
||||||
|
tail_recurse:
|
||||||
|
if (count < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* The symbol table and DWARF tables, which is all we use this
|
||||||
|
routine for, tend to be roughly sorted. Pick the middle element
|
||||||
|
in the array as our pivot point, so that we are more likely to
|
||||||
|
cut the array in half for each recursion step. */
|
||||||
|
swap (base, base + (count / 2) * size, size);
|
||||||
|
|
||||||
|
mid = 0;
|
||||||
|
for (i = 1; i < count; i++)
|
||||||
|
{
|
||||||
|
if ((*compar) (base, base + i * size) > 0)
|
||||||
|
{
|
||||||
|
++mid;
|
||||||
|
if (i != mid)
|
||||||
|
swap (base + mid * size, base + i * size, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mid > 0)
|
||||||
|
swap (base, base + mid * size, size);
|
||||||
|
|
||||||
|
/* Recurse with the smaller array, loop with the larger one. That
|
||||||
|
ensures that our maximum stack depth is log count. */
|
||||||
|
if (2 * mid < count)
|
||||||
|
{
|
||||||
|
backtrace_qsort (base, mid, size, compar);
|
||||||
|
base += (mid + 1) * size;
|
||||||
|
count -= mid + 1;
|
||||||
|
goto tail_recurse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
backtrace_qsort (base + (mid + 1) * size, count - (mid + 1),
|
||||||
|
size, compar);
|
||||||
|
count = mid;
|
||||||
|
goto tail_recurse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
76
libbacktrace/state.cpp
Normal file
76
libbacktrace/state.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* state.c -- Create the backtrace state.
|
||||||
|
Copyright (C) 2012-2018 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.hpp"
|
||||||
|
#include "internal.hpp"
|
||||||
|
|
||||||
|
namespace tracy
|
||||||
|
{
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user