From 552b7d743dd6afa531cc28bd6ff0d4407e3b8561 Mon Sep 17 00:00:00 2001 From: John Viega Date: Mon, 15 Jul 2024 02:59:52 -0400 Subject: [PATCH] Turned memcheck back on --- include/con4m.h | 4 ---- include/con4m/datatypes/memory.h | 8 +++++--- src/con4m/collect.c | 16 +++++++++++++++- src/con4m/gcbase.c | 8 ++++---- src/con4m/types.c | 11 +++++++++++ 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/include/con4m.h b/include/con4m.h index f691639e..5c3e023a 100644 --- a/include/con4m.h +++ b/include/con4m.h @@ -2,10 +2,6 @@ #define C4M_DEBUG // Get backtrace on exceptions. -#ifdef C4M_FULL_MEMCHECK -#undef C4M_FULL_MEMCHECK -#endif - // #define C4M_FULL_MEMCHECK // #define C4M_STRICT_MEMCHECK // #define C4M_TRACE_GC diff --git a/include/con4m/datatypes/memory.h b/include/con4m/datatypes/memory.h index 7197c1a3..32576c53 100644 --- a/include/con4m/datatypes/memory.h +++ b/include/con4m/datatypes/memory.h @@ -56,13 +56,15 @@ typedef struct c4m_alloc_hdr { // bits that correspond to words with pointers should be set. c4m_mem_scan_fn scan_fn; -#ifdef C4M_FULL_MEMCHECK - uint64_t *end_guard_loc; -#endif #if defined(C4M_GC_STATS) || defined(C4M_DEBUG) char *alloc_file; int alloc_line; #endif + +#ifdef C4M_FULL_MEMCHECK + uint64_t *end_guard_loc; +#endif + // Set to 'true' if this object requires finalization. This is // necessary, even though the arena tracks allocations needing // finalization, because resizes could move the pointer. diff --git a/src/con4m/collect.c b/src/con4m/collect.c index 14b1db15..93cb25b0 100644 --- a/src/con4m/collect.c +++ b/src/con4m/collect.c @@ -692,7 +692,6 @@ _c4m_memcheck_raw_alloc(void *a, char *file, int line) file, line, a); - return; abort(); } @@ -819,6 +818,20 @@ c4m_alloc_display_rear_guard_error(c4m_alloc_hdr *hdr, #endif } +static void +show_next_n_allocs(c4m_shadow_alloc_t *a, int n) +{ + printf("Next allocs:\n"); + + while (a && n) { + printf("%s:%d (@%p; %d bytes)\n", a->file, a->line, a->start, a->len); + a = a->next; + n -= 1; + } + + abort(); +} + static void memcheck_validate_old_records(c4m_arena_t *from_space) { @@ -845,6 +858,7 @@ memcheck_validate_old_records(c4m_arena_t *from_space) a->file, a->line, false); + show_next_n_allocs(next, 1000); } if (a->start->fw_addr != NULL) { diff --git a/src/con4m/gcbase.c b/src/con4m/gcbase.c index 390c9485..02fbc792 100644 --- a/src/con4m/gcbase.c +++ b/src/con4m/gcbase.c @@ -15,7 +15,7 @@ thread_local uint32_t c4m_total_allocs = 0; #ifdef C4M_FULL_MEMCHECK #ifndef C4M_MEMCHECK_RING_SZ // Must be a power of 2. -#define C4M_MEMCHECK_RING_SZ 64 +#define C4M_MEMCHECK_RING_SZ 128 #endif #if C4M_MEMCHECK_RING_SZ != 0 #define C4M_USE_RING @@ -641,7 +641,7 @@ c4m_alloc_from_arena(c4m_arena_t **arena_ptr, #endif #ifdef C4M_FULL_MEMCHECK - len = len + 8; // Ensure room for sentinel. + len += 8; // Ensure room for sentinel. #endif c4m_arena_t *arena = *arena_ptr; @@ -688,7 +688,7 @@ c4m_alloc_from_arena(c4m_arena_t **arena_ptr, raw->scan_fn = scan_fn; #ifdef C4M_FULL_MEMCHECK - uint64_t *end_guard_addr = &raw->data[wordlen - 1]; + uint64_t *end_guard_addr = &raw->data[wordlen - 2]; c4m_shadow_alloc_t *record = c4m_rc_alloc(sizeof(c4m_shadow_alloc_t)); record->start = raw; @@ -713,7 +713,7 @@ c4m_alloc_from_arena(c4m_arena_t **arena_ptr, // Duplicated in the header for spot-checking; this can get corrupted; // the out-of-heap list is better, but we don't want to bother searching // through the whole heap. - raw->end_guard_loc = record->end; + raw->end_guard_loc = end_guard_addr; assert(*raw->end_guard_loc == c4m_end_guard); diff --git a/src/con4m/types.c b/src/con4m/types.c index 2a3acb5d..f44c37b6 100644 --- a/src/con4m/types.c +++ b/src/con4m/types.c @@ -277,6 +277,7 @@ c4m_early_alloc_type(c4m_base_obj_t **bptr) base->concrete_type = c4m_bi_types[C4M_T_TYPESPEC]; result->details = info; + info->items = NULL; info->base_type = tspec; return result; @@ -400,9 +401,18 @@ internal_type_hash(c4m_type_t *node, type_hash_ctx *ctx) c4m_sha_int_update(ctx->sha, num_tvars); c4m_sha_int_update(ctx->sha, node->typeid); break; + case C4M_DT_KIND_primitive: + case C4M_DT_KIND_box: + case C4M_DT_KIND_nil: + case C4M_DT_KIND_internal: + return; default:; // Do nothing. } + if (!deets->items) { + return; + } + size_t n = c4m_list_len(deets->items); c4m_sha_int_update(ctx->sha, n); @@ -1690,6 +1700,7 @@ setup_primitive_types() c4m_type_t *t = c4m_early_alloc_type(&base); t->typeid = i; t->details->base_type = one_spec; + t->details->items = NULL; c4m_bi_types[i] = t; if (i) {