glibc/debug/backtracesyms.c

160 lines
4.8 KiB
C
Raw Permalink Normal View History

/* Return list with names for address in backtrace.
Copyright (C) 1998-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <assert.h>
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ldsodefs.h>
#if __ELF_NATIVE_CLASS == 32
# define WORD_WIDTH 8
#else
2013-08-29 09:08:54 +02:00
/* We assume 64bits. */
# define WORD_WIDTH 16
#endif
char **
Convert 113 more function definitions to prototype style (files with assertions). This mostly automatically-generated patch converts 113 function definitions in glibc from old-style K&R to prototype-style. Following my other recent such patches, this one deals with the case of function definitions in files that either contain assertions or where grep suggested they might contain assertions - and thus where it isn't possible to use a simple object code comparison as a sanity check on the correctness of the patch, because line numbers are changed. A few such automatically-generated changes needed to be supplemented by manual changes for the result to compile. openat64 had a prototype declaration with "..." but an old-style definition in sysdeps/unix/sysv/linux/dl-openat64.c, and "..." needed adding to the generated prototype in the definition (I've filed <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68024> for diagnosing such cases in GCC; the old state was undefined behavior not requiring a diagnostic, but one seems a good idea). In addition, as Florian has noted regparm attribute mismatches between declaration and definition are only diagnosed for prototype definitions, and five functions needed internal_function added to their definitions (in the case of __pthread_mutex_cond_lock, via the macro definition of __pthread_mutex_lock) to compile on i386. After this patch is in, remaining old-style definitions are probably most readily fixed manually before we can turn on -Wold-style-definition for all builds. Tested for x86_64 and x86 (testsuite). * crypt/md5-crypt.c (__md5_crypt_r): Convert to prototype-style function definition. * crypt/sha256-crypt.c (__sha256_crypt_r): Likewise. * crypt/sha512-crypt.c (__sha512_crypt_r): Likewise. * debug/backtracesyms.c (__backtrace_symbols): Likewise. * elf/dl-minimal.c (_itoa): Likewise. * hurd/hurdmalloc.c (malloc): Likewise. (free): Likewise. (realloc): Likewise. * inet/inet6_option.c (inet6_option_space): Likewise. (inet6_option_init): Likewise. (inet6_option_append): Likewise. (inet6_option_alloc): Likewise. (inet6_option_next): Likewise. (inet6_option_find): Likewise. * io/ftw.c (FTW_NAME): Likewise. (NFTW_NAME): Likewise. (NFTW_NEW_NAME): Likewise. (NFTW_OLD_NAME): Likewise. * libio/iofwide.c (_IO_fwide): Likewise. * libio/strops.c (_IO_str_init_static_internal): Likewise. (_IO_str_init_static): Likewise. (_IO_str_init_readonly): Likewise. (_IO_str_overflow): Likewise. (_IO_str_underflow): Likewise. (_IO_str_count): Likewise. (_IO_str_seekoff): Likewise. (_IO_str_pbackfail): Likewise. (_IO_str_finish): Likewise. * libio/wstrops.c (_IO_wstr_init_static): Likewise. (_IO_wstr_overflow): Likewise. (_IO_wstr_underflow): Likewise. (_IO_wstr_count): Likewise. (_IO_wstr_seekoff): Likewise. (_IO_wstr_pbackfail): Likewise. (_IO_wstr_finish): Likewise. * locale/programs/localedef.c (normalize_codeset): Likewise. * locale/programs/locarchive.c (add_locale_to_archive): Likewise. (add_locales_to_archive): Likewise. (delete_locales_from_archive): Likewise. * malloc/malloc.c (__libc_mallinfo): Likewise. * math/gen-auto-libm-tests.c (init_fp_formats): Likewise. * misc/tsearch.c (__tfind): Likewise. * nptl/pthread_attr_destroy.c (__pthread_attr_destroy): Likewise. * nptl/pthread_attr_getdetachstate.c (__pthread_attr_getdetachstate): Likewise. * nptl/pthread_attr_getguardsize.c (pthread_attr_getguardsize): Likewise. * nptl/pthread_attr_getinheritsched.c (__pthread_attr_getinheritsched): Likewise. * nptl/pthread_attr_getschedparam.c (__pthread_attr_getschedparam): Likewise. * nptl/pthread_attr_getschedpolicy.c (__pthread_attr_getschedpolicy): Likewise. * nptl/pthread_attr_getscope.c (__pthread_attr_getscope): Likewise. * nptl/pthread_attr_getstack.c (__pthread_attr_getstack): Likewise. * nptl/pthread_attr_getstackaddr.c (__pthread_attr_getstackaddr): Likewise. * nptl/pthread_attr_getstacksize.c (__pthread_attr_getstacksize): Likewise. * nptl/pthread_attr_init.c (__pthread_attr_init_2_1): Likewise. (__pthread_attr_init_2_0): Likewise. * nptl/pthread_attr_setdetachstate.c (__pthread_attr_setdetachstate): Likewise. * nptl/pthread_attr_setguardsize.c (pthread_attr_setguardsize): Likewise. * nptl/pthread_attr_setinheritsched.c (__pthread_attr_setinheritsched): Likewise. * nptl/pthread_attr_setschedparam.c (__pthread_attr_setschedparam): Likewise. * nptl/pthread_attr_setschedpolicy.c (__pthread_attr_setschedpolicy): Likewise. * nptl/pthread_attr_setscope.c (__pthread_attr_setscope): Likewise. * nptl/pthread_attr_setstack.c (__pthread_attr_setstack): Likewise. * nptl/pthread_attr_setstackaddr.c (__pthread_attr_setstackaddr): Likewise. * nptl/pthread_attr_setstacksize.c (__pthread_attr_setstacksize): Likewise. * nptl/pthread_condattr_setclock.c (pthread_condattr_setclock): Likewise. * nptl/pthread_create.c (__find_in_stack_list): Likewise. * nptl/pthread_getattr_np.c (pthread_getattr_np): Likewise. * nptl/pthread_mutex_cond_lock.c (__pthread_mutex_lock): Define to use internal_function. * nptl/pthread_mutex_init.c (__pthread_mutex_init): Convert to prototype-style function definition. * nptl/pthread_mutex_lock.c (__pthread_mutex_lock): Likewise. (__pthread_mutex_cond_lock_adjust): Likewise. Use internal_function. * nptl/pthread_mutex_timedlock.c (pthread_mutex_timedlock): Convert to prototype-style function definition. * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise. * nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Likewise. (__pthread_mutex_unlock): Likewise. * nptl_db/td_ta_clear_event.c (td_ta_clear_event): Likewise. * nptl_db/td_ta_set_event.c (td_ta_set_event): Likewise. * nptl_db/td_thr_clear_event.c (td_thr_clear_event): Likewise. * nptl_db/td_thr_event_enable.c (td_thr_event_enable): Likewise. * nptl_db/td_thr_set_event.c (td_thr_set_event): Likewise. * nss/makedb.c (process_input): Likewise. * posix/fnmatch.c (__strchrnul): Likewise. (__wcschrnul): Likewise. (fnmatch): Likewise. * posix/fnmatch_loop.c (FCT): Likewise. * posix/glob.c (globfree): Likewise. (__glob_pattern_type): Likewise. (__glob_pattern_p): Likewise. * posix/regcomp.c (re_compile_pattern): Likewise. (re_set_syntax): Likewise. (re_compile_fastmap): Likewise. (regcomp): Likewise. (regerror): Likewise. (regfree): Likewise. * posix/regexec.c (regexec): Likewise. (re_match): Likewise. (re_search): Likewise. (re_match_2): Likewise. (re_search_2): Likewise. (re_search_stub): Likewise. Use internal_function (re_copy_regs): Likewise. (re_set_registers): Convert to prototype-style function definition. (prune_impossible_nodes): Likewise. Use internal_function. * resolv/inet_net_pton.c (inet_net_pton): Convert to prototype-style function definition. (inet_net_pton_ipv4): Likewise. * stdlib/strtod_l.c (____STRTOF_INTERNAL): Likewise. * sysdeps/pthread/aio_cancel.c (aio_cancel): Likewise. * sysdeps/pthread/aio_suspend.c (aio_suspend): Likewise. * sysdeps/pthread/timer_delete.c (timer_delete): Likewise. * sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise. Make variadic. * time/strptime_l.c (localtime_r): Convert to prototype-style function definition. * wcsmbs/mbsnrtowcs.c (__mbsnrtowcs): Likewise. * wcsmbs/mbsrtowcs_l.c (__mbsrtowcs_l): Likewise. * wcsmbs/wcsnrtombs.c (__wcsnrtombs): Likewise. * wcsmbs/wcsrtombs.c (__wcsrtombs): Likewise.
2015-10-20 13:54:09 +02:00
__backtrace_symbols (void *const *array, int size)
{
Dl_info info[size];
int status[size];
int cnt;
size_t total = 0;
char **result;
2022-08-11 20:23:08 +02:00
#if defined __e2k__
const char signal_handler_called[] = "<signal handler called>";
#endif /* __e2k__ */
/* Fill in the information we can get from `dladdr'. */
for (cnt = 0; cnt < size; ++cnt)
{
struct link_map *map;
status[cnt] = _dl_addr (array[cnt], &info[cnt], &map, NULL);
if (status[cnt] && info[cnt].dli_fname && info[cnt].dli_fname[0] != '\0')
{
/* We have some info, compute the length of the string which will be
"<file-name>(<sym-name>+offset) [address]. */
total += (strlen (info[cnt].dli_fname ?: "")
+ strlen (info[cnt].dli_sname ?: "")
+ 3 + WORD_WIDTH + 3 + WORD_WIDTH + 5);
/* The load bias is more useful to the user than the load
address. The use of these addresses is to calculate an
address in the ELF file, so its prelinked bias is not
something we want to subtract out. */
2022-08-11 20:23:08 +02:00
#if !defined __ptr128__
info[cnt].dli_fbase = (void *) map->l_addr;
2022-08-11 20:23:08 +02:00
#else /* defined __ptr128__ */
/* TODO: find out why they prefer to set `dli_fbase' to L_ADDR for
ordinary modes above unlike dl-addr.c where it's set to
L_MAP_START. I try to stupidly imitate their behaviour for now. */
info[cnt].dli_tbase = map->l_code_addr;
info[cnt].dli_dbase = map->l_addr;
#endif /* defined __ptr128__ */
}
2022-08-11 20:23:08 +02:00
#if defined __e2k__
else if (array[cnt] == (void *) -1UL)
total += sizeof (signal_handler_called);
#endif /* __e2k__ */
else
total += 5 + WORD_WIDTH;
}
/* Allocate memory for the result. */
result = (char **) malloc (size * sizeof (char *) + total);
if (result != NULL)
{
char *last = (char *) (result + size);
for (cnt = 0; cnt < size; ++cnt)
{
result[cnt] = last;
if (status[cnt]
&& info[cnt].dli_fname != NULL && info[cnt].dli_fname[0] != '\0')
{
if (info[cnt].dli_sname == NULL)
2022-08-11 20:23:08 +02:00
{
/* We found no symbol name to use, so describe it as
relative to the file. */
#if !defined __ptr128__
info[cnt].dli_saddr = info[cnt].dli_fbase;
#else /* defined __ptr128__ */
/* FIXME: stupidly make use of dli_tbase here for now since
backtrace addresses are likely to belong to CUD. However,
some sort of test should be probably implemented to ensure
that this is the case. */
info[cnt].dli_saddr = info[cnt].dli_tbase;
#endif /* defined __ptr128__ */
}
if (info[cnt].dli_sname == NULL && info[cnt].dli_saddr == 0)
last += 1 + sprintf (last, "%s(%s) [%p]",
info[cnt].dli_fname ?: "",
info[cnt].dli_sname ?: "",
array[cnt]);
else
{
char sign;
ptrdiff_t offset;
if (array[cnt] >= (void *) info[cnt].dli_saddr)
{
sign = '+';
2022-08-11 20:23:08 +02:00
offset = (
#if defined __ptr128__
(ptrdiff_t)
#endif
array[cnt] - info[cnt].dli_saddr);
}
else
{
sign = '-';
2022-08-11 20:23:08 +02:00
offset = (info[cnt].dli_saddr
-
#if defined __ptr128__
(ptrdiff_t)
#endif /* defined __ptr128__ */
array[cnt]);
}
last += 1 + sprintf (last, "%s(%s%c%#tx) [%p]",
info[cnt].dli_fname ?: "",
info[cnt].dli_sname ?: "",
sign, offset, array[cnt]);
}
}
2022-08-11 20:23:08 +02:00
#if defined __e2k__
else if (array[cnt] == (void *) -1UL)
/* `1 + ' accounts for the trailing '\0'. */
last += 1 + sprintf (last, "%s", signal_handler_called);
#endif /* __e2k__ */
else
last += 1 + sprintf (last, "[%p]", array[cnt]);
}
assert (last <= (char *) result + size * sizeof (char *) + total);
}
return result;
}
weak_alias (__backtrace_symbols, backtrace_symbols)