Skip to content

Commit

Permalink
Define GC_return_addr_t to hold return address info instead of GC_word
Browse files Browse the repository at this point in the history
Issue #627 (bdwgc).

GC_return_addr_t is a type to hold a function return address (pointer).
Never used for calling a function.

* dbg_mlc.c [GC_ADD_CALLER && HAVE_DLADDR
&& GC_HAVE_RETURN_ADDR_PARENT] (GC_caller_func_offset): Define if macro
unless FUNCPTR_IS_DATAPTR.
* dbg_mlc.c [GC_ADD_CALLER && HAVE_DLADDR && FUNCPTR_IS_DATAPTR
&& GC_HAVE_RETURN_ADDR_PARENT] (GC_caller_func_offset): Rename ad to
ra an change its type from word to GC_return_addr_t; replace char*
casts to ptr_t ones.
* include/gc/gc.h [(GC_CAN_SAVE_CALL_STACKS || GC_ADD_CALLER)
&& !GC_RETURN_ADDR_T_DEFINED] (GC_return_addr_t): New type.
* include/gc/gc.h [(GC_CAN_SAVE_CALL_STACKS || GC_ADD_CALLER)
&& !GC_RETURN_ADDR_T_DEFINED] (GC_RETURN_ADDR_T_DEFINED): Define macro.
* include/gc/gc.h [GC_ADD_CALLER] (GC_EXTRA_PARAMS): Change type of ra
from GC_word to GC_return_addr_t.
* include/gc/gc_config_macros.h (GC_RETURN_ADDR): Cast to
GC_return_addr_t.
* include/private/gc_priv.h [NEED_CALLINFO] (callinfo.ci_pc): Change
type from word to GC_return_addr_t.
* os_dep.c [SAVE_CALL_CHAIN] (GC_save_callers_no_unlock,
GC_save_callers): Cast value stored to ci_pc field to GC_return_addr_t
instead of word.
* os_dep.c [SAVE_CALL_CHAIN] (GC_save_callers): Do not cast
fp->fr_arg[i] to signed_word.
* os_dep.c [NEED_CALLINFO && GC_HAVE_BUILTIN_BACKTRACE
&& !GC_BACKTRACE_SYMBOLS_BROKEN] (GC_print_callers): Do not call
backtrace_symbols() and free() unless FUNCPTR_IS_DATAPTR.
  • Loading branch information
ivmai committed Jun 14, 2024
1 parent 4f73bae commit b2552e0
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 24 deletions.
14 changes: 9 additions & 5 deletions dbg_mlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,23 +492,27 @@ GC_API void GC_CALL GC_debug_register_displacement(size_t offset)
}

#ifdef GC_ADD_CALLER
# if defined(HAVE_DLADDR) && defined(GC_HAVE_RETURN_ADDR_PARENT)
# if defined(HAVE_DLADDR) && defined(GC_HAVE_RETURN_ADDR_PARENT) \
&& defined(FUNCPTR_IS_DATAPTR)
# include <dlfcn.h>

STATIC void GC_caller_func_offset(word ad, const char **symp, int *offp)
STATIC void GC_caller_func_offset(GC_return_addr_t ra, const char **symp,
int *offp)
{
Dl_info caller;

if (ad && dladdr((void *)ad, &caller) && caller.dli_sname != NULL) {
if (ra != 0 && dladdr((void *)ra, &caller)
&& caller.dli_sname != NULL) {
*symp = caller.dli_sname;
*offp = (int)((char *)ad - (char *)caller.dli_saddr);
*offp = (int)((ptr_t)ra - (ptr_t)caller.dli_saddr);
}
if (NULL == *symp) {
*symp = "unknown";
/* Note: *offp is unchanged. */
}
}
# else
# define GC_caller_func_offset(ad, symp, offp) (void)(*(symp) = "unknown")
# define GC_caller_func_offset(ra, symp, offp) (void)(*(symp) = "unknown")
# endif
#endif /* GC_ADD_CALLER */

Expand Down
10 changes: 9 additions & 1 deletion include/gc/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1034,9 +1034,17 @@ GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL
GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL
GC_malloc_atomic_ignore_off_page(size_t /* lb */);

#if (defined(GC_CAN_SAVE_CALL_STACKS) || defined(GC_ADD_CALLER)) \
&& !defined(GC_RETURN_ADDR_T_DEFINED)
/* A type to hold a function return address (pointer). Never used */
/* for calling a function. */
typedef void (*GC_return_addr_t)(void);
# define GC_RETURN_ADDR_T_DEFINED
#endif /* GC_CAN_SAVE_CALL_STACKS || GC_ADD_CALLER */

#ifdef GC_ADD_CALLER
# define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__
# define GC_EXTRA_PARAMS GC_word ra, const char * s, int i
# define GC_EXTRA_PARAMS GC_return_addr_t ra, const char * s, int i
#else
# define GC_EXTRAS __FILE__, __LINE__
# define GC_EXTRA_PARAMS const char * s, int i
Expand Down
16 changes: 7 additions & 9 deletions include/gc/gc_config_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@

#if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720
# define GC_ADD_CALLER
# define GC_RETURN_ADDR (GC_word)__return_address
# define GC_RETURN_ADDR (GC_return_addr_t)__return_address
#endif

#if defined(__linux__) || defined(__GLIBC__)
Expand All @@ -356,11 +356,8 @@
# define GC_HAVE_BUILTIN_BACKTRACE
#endif

#if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS)
# define GC_CAN_SAVE_CALL_STACKS
#endif

#if defined(__sparc__)
#if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS) \
|| defined(__sparc__)
# define GC_CAN_SAVE_CALL_STACKS
#endif

Expand All @@ -380,19 +377,20 @@
# if GC_GNUC_PREREQ(2, 95)
/* gcc knows how to retrieve return address, but we don't know */
/* how to generate call stacks. */
# define GC_RETURN_ADDR (GC_word)__builtin_return_address(0)
# define GC_RETURN_ADDR (GC_return_addr_t)__builtin_return_address(0)
# if GC_GNUC_PREREQ(4, 0) && (defined(__i386__) || defined(__amd64__) \
|| defined(__x86_64__) /* and probably others... */) \
&& !defined(GC_NO_RETURN_ADDR_PARENT)
# define GC_HAVE_RETURN_ADDR_PARENT
# define GC_RETURN_ADDR_PARENT \
(GC_word)__builtin_extract_return_addr(__builtin_return_address(1))
(GC_return_addr_t)__builtin_extract_return_addr( \
__builtin_return_address(1))
/* Note: a compiler might complain that calling */
/* __builtin_return_address with a nonzero argument is unsafe. */
# endif
# else
/* Just pass 0 for gcc compatibility. */
# define GC_RETURN_ADDR 0
# define GC_RETURN_ADDR ((GC_return_addr_t)0)
# endif
#endif /* !GC_CAN_SAVE_CALL_STACKS */

Expand Down
2 changes: 1 addition & 1 deletion include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ EXTERN_C_BEGIN

#ifdef NEED_CALLINFO
struct callinfo {
word ci_pc; /* pc of caller, not callee */
GC_return_addr_t ci_pc; /* pc of caller, not callee */
# if NARGS > 0
GC_hidden_pointer ci_arg[NARGS]; /* hide to avoid retention */
# endif
Expand Down
17 changes: 9 additions & 8 deletions os_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -5276,7 +5276,7 @@ GC_API int GC_CALL GC_get_pages_executable(void)
struct callinfo info[NFRAMES])
{
GC_ASSERT(I_HOLD_LOCK());
info[0].ci_pc = (word)(&GC_save_callers_no_unlock);
info[0].ci_pc = (GC_return_addr_t)(&GC_save_callers_no_unlock);
BZERO(&info[1], sizeof(void *) * (NFRAMES - 1));
}
# endif
Expand All @@ -5295,7 +5295,7 @@ GC_API int GC_CALL GC_get_pages_executable(void)
GC_STATIC_ASSERT(sizeof(struct callinfo) == sizeof(void *));
# ifdef REDIRECT_MALLOC
if (GC_in_save_callers) {
info[0].ci_pc = (word)(&GC_save_callers);
info[0].ci_pc = (GC_return_addr_t)(&GC_save_callers);
BZERO(&info[1], sizeof(void *) * (NFRAMES - 1));
return;
}
Expand Down Expand Up @@ -5363,11 +5363,11 @@ GC_API int GC_CALL GC_get_pages_executable(void)
int i;
# endif

info[nframes].ci_pc = fp -> FR_SAVPC;
info[nframes].ci_pc = (GC_return_addr_t)(fp -> FR_SAVPC);
# if NARGS > 0
for (i = 0; i < NARGS; i++) {
info[nframes].ci_arg[i] =
GC_HIDE_NZ_POINTER((void *)(signed_word)(fp -> fr_arg[i]));
GC_HIDE_NZ_POINTER((void *)(fp -> fr_arg[i]));
}
# endif
}
Expand Down Expand Up @@ -5437,9 +5437,9 @@ GC_API int GC_CALL GC_get_pages_executable(void)
char buf[40];
char *name;
# if defined(GC_HAVE_BUILTIN_BACKTRACE) \
&& !defined(GC_BACKTRACE_SYMBOLS_BROKEN)
char **sym_name =
backtrace_symbols((void **)(&(info[i].ci_pc)), 1);
&& !defined(GC_BACKTRACE_SYMBOLS_BROKEN) \
&& defined(FUNCPTR_IS_DATAPTR)
char **sym_name = backtrace_symbols((void **)&info[i].ci_pc, 1);
if (sym_name != NULL) {
name = sym_name[0];
} else
Expand Down Expand Up @@ -5550,7 +5550,8 @@ GC_API int GC_CALL GC_get_pages_executable(void)
# endif /* LINUX */
GC_err_printf("\t\t%s\n", name);
# if defined(GC_HAVE_BUILTIN_BACKTRACE) \
&& !defined(GC_BACKTRACE_SYMBOLS_BROKEN)
&& !defined(GC_BACKTRACE_SYMBOLS_BROKEN) \
&& defined(FUNCPTR_IS_DATAPTR)
if (sym_name != NULL)
free(sym_name); /* May call GC_[debug_]free; that's OK */
# endif
Expand Down

0 comments on commit b2552e0

Please sign in to comment.