From 74162906f3359f2b75b018ee0a2c39725306111f Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Thu, 30 Jan 2014 22:18:23 +0900 Subject: [PATCH] Adding optional stack traces on potential GC misses detected by conservative tracing. --- gc.c | 13 +++++++++++++ include/chibi/features.h | 12 ++++++++++++ include/chibi/sexp.h | 5 +++++ sexp.c | 8 ++++++++ 4 files changed, 38 insertions(+) diff --git a/gc.c b/gc.c index eb68c300..9c49e01a 100644 --- a/gc.c +++ b/gc.c @@ -223,6 +223,18 @@ int stack_references_pointer_p (sexp ctx, sexp x) { return 0; } +#if SEXP_USE_TRACK_ALLOC_BACKTRACE +void sexp_print_gc_trace(sexp ctx, sexp p) { + int i; + char **debug_text = backtrace_symbols(p->backtrace, SEXP_BACKTRACE_SIZE); + for (i=0; i < SEXP_BACKTRACE_SIZE; i++) + fprintf(stderr, SEXP_BANNER(" : %s"), debug_text[i]); + free(debug_text); +} +#else +#define sexp_print_gc_trace(ctx, p) +#endif + void sexp_conservative_mark (sexp ctx) { sexp_heap h = sexp_context_heap(ctx); sexp p, end; @@ -247,6 +259,7 @@ void sexp_conservative_mark (sexp ctx) { if (p && sexp_pointerp(p)) { fprintf(stderr, SEXP_BANNER("MISS: %p [%d]: %s"), p, sexp_pointer_tag(p), sexp_pointer_source(p)); + sexp_print_gc_trace(ctx, p); fflush(stderr); } #endif diff --git a/include/chibi/features.h b/include/chibi/features.h index bfb6933a..25fa7c7c 100644 --- a/include/chibi/features.h +++ b/include/chibi/features.h @@ -87,6 +87,10 @@ /* uncomment this to track what C source line each object is allocated from */ /* #define SEXP_USE_TRACK_ALLOC_SOURCE 1 */ +/* uncomment this to take a short backtrace of where each object is */ +/* allocated from */ +/* #define SEXP_USE_TRACK_ALLOC_BACKTRACE 1 */ + /* uncomment this to add additional native gc checks to verify a magic header */ /* #define SEXP_USE_HEADER_MAGIC 1 */ @@ -372,6 +376,14 @@ #define SEXP_USE_TRACK_ALLOC_SOURCE SEXP_USE_DEBUG_GC > 2 #endif +#ifndef SEXP_USE_TRACK_ALLOC_BACKTRACE +#define SEXP_USE_TRACK_ALLOC_BACKTRACE SEXP_USE_TRACK_ALLOC_SOURCE +#endif + +#ifndef SEXP_BACKTRACE_SIZE +#define SEXP_BACKTRACE_SIZE 3 +#endif + #ifndef SEXP_USE_HEADER_MAGIC #define SEXP_USE_HEADER_MAGIC 0 #endif diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index b4f5ad6e..c410c0dc 100755 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -75,6 +75,10 @@ typedef unsigned long size_t; #endif #endif +#if SEXP_USE_TRACK_ALLOC_BACKTRACE +#include +#endif + #include #include @@ -294,6 +298,7 @@ struct sexp_struct { unsigned int syntacticp:1; #if SEXP_USE_TRACK_ALLOC_SOURCE const char* source; + void* backtrace[SEXP_BACKTRACE_SIZE]; #endif #if SEXP_USE_HEADER_MAGIC unsigned int magic; diff --git a/sexp.c b/sexp.c index b5dcea02..03ad1834 100644 --- a/sexp.c +++ b/sexp.c @@ -62,11 +62,19 @@ sexp sexp_push_op(sexp ctx, sexp* loc, sexp x) { #endif sexp sexp_alloc_tagged_aux(sexp ctx, size_t size, sexp_uint_t tag sexp_current_source_param) { +#if SEXP_USE_TRACK_ALLOC_BACKTRACE + int i; + void* trace[SEXP_BACKTRACE_SIZE + 1]; +#endif sexp res = (sexp) sexp_alloc(ctx, size); if (res && ! sexp_exceptionp(res)) { sexp_pointer_tag(res) = tag; #if SEXP_USE_TRACK_ALLOC_SOURCE sexp_pointer_source(res) = source; +#if SEXP_USE_TRACK_ALLOC_BACKTRACE + backtrace(trace, SEXP_BACKTRACE_SIZE + 1); + for (i=0; ibacktrace[i] = trace[i+1]; +#endif #endif #if SEXP_USE_HEADER_MAGIC sexp_pointer_magic(res) = SEXP_POINTER_MAGIC;