📄 dbg_mlc.c
字号:
clobbered = GC_check_annotated_obj((oh *)base); if (clobbered != 0) { if (((oh *)base) -> oh_sz == GC_size(base)) { GC_err_printf0( "GC_debug_free: found previously deallocated (?) object at "); } else { GC_err_printf0("GC_debug_free: found smashed location at "); } GC_print_smashed_obj(p, clobbered); } /* Invalidate size */ ((oh *)base) -> oh_sz = GC_size(base);# endif /* SHORT_DBG_HDRS */ } if (GC_find_leak) { GC_free(base); } else { register hdr * hhdr = HDR(p); GC_bool uncollectable = FALSE; if (hhdr -> hb_obj_kind == UNCOLLECTABLE) { uncollectable = TRUE; }# ifdef ATOMIC_UNCOLLECTABLE if (hhdr -> hb_obj_kind == AUNCOLLECTABLE) { uncollectable = TRUE; }# endif if (uncollectable) { GC_free(base); } else { size_t i; size_t obj_sz = hhdr -> hb_sz - BYTES_TO_WORDS(sizeof(oh)); for (i = 0; i < obj_sz; ++i) ((word *)p)[i] = 0xdeadbeef; GC_ASSERT((word *)p + i == (word *)base + hhdr -> hb_sz); } } /* !GC_find_leak */}#ifdef THREADSextern void GC_free_inner(GC_PTR p);/* Used internally; we assume it's called correctly. */void GC_debug_free_inner(GC_PTR p){ GC_free_inner(GC_base(p));}#endif# ifdef __STDC__ GC_PTR GC_debug_realloc(GC_PTR p, size_t lb, GC_EXTRA_PARAMS)# else GC_PTR GC_debug_realloc(p, lb, s, i) GC_PTR p; size_t lb; char *s; int i;# endif{ register GC_PTR base = GC_base(p); register ptr_t clobbered; register GC_PTR result; register size_t copy_sz = lb; register size_t old_sz; register hdr * hhdr; if (p == 0) return(GC_debug_malloc(lb, OPT_RA s, i)); if (base == 0) { GC_err_printf1( "Attempt to reallocate invalid pointer %lx\n", (unsigned long)p); ABORT("realloc(invalid pointer)"); } if ((ptr_t)p - (ptr_t)base != sizeof(oh)) { GC_err_printf1( "GC_debug_realloc called on pointer %lx wo debugging info\n", (unsigned long)p); return(GC_realloc(p, lb)); } hhdr = HDR(base); switch (hhdr -> hb_obj_kind) {# ifdef STUBBORN_ALLOC case STUBBORN: result = GC_debug_malloc_stubborn(lb, OPT_RA s, i); break;# endif case NORMAL: result = GC_debug_malloc(lb, OPT_RA s, i); break; case PTRFREE: result = GC_debug_malloc_atomic(lb, OPT_RA s, i); break; case UNCOLLECTABLE: result = GC_debug_malloc_uncollectable(lb, OPT_RA s, i); break;# ifdef ATOMIC_UNCOLLECTABLE case AUNCOLLECTABLE: result = GC_debug_malloc_atomic_uncollectable(lb, OPT_RA s, i); break;# endif default: GC_err_printf0("GC_debug_realloc: encountered bad kind\n"); ABORT("bad kind"); }# ifdef SHORT_DBG_HDRS old_sz = GC_size(base) - sizeof(oh);# else clobbered = GC_check_annotated_obj((oh *)base); if (clobbered != 0) { GC_err_printf0("GC_debug_realloc: found smashed location at "); GC_print_smashed_obj(p, clobbered); } old_sz = ((oh *)base) -> oh_sz;# endif if (old_sz < copy_sz) copy_sz = old_sz; if (result == 0) return(0); BCOPY(p, result, copy_sz); GC_debug_free(p); return(result);}#ifndef SHORT_DBG_HDRS/* List of smashed objects. We defer printing these, since we can't *//* always print them nicely with the allocation lock held. *//* We put them here instead of in GC_arrays, since it may be useful to *//* be able to look at them with the debugger. */#define MAX_SMASHED 20ptr_t GC_smashed[MAX_SMASHED];unsigned GC_n_smashed = 0;# if defined(__STDC__) || defined(__cplusplus) void GC_add_smashed(ptr_t smashed)# else void GC_add_smashed(smashed) ptr_t smashed;#endif{ GC_ASSERT(GC_is_marked(GC_base(smashed))); GC_smashed[GC_n_smashed] = smashed; if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed; /* In case of overflow, we keep the first MAX_SMASHED-1 */ /* entries plus the last one. */ GC_have_errors = TRUE;}/* Print all objects on the list. Clear the list. */void GC_print_all_smashed_proc (){ unsigned i; GC_ASSERT(!I_HOLD_LOCK()); if (GC_n_smashed == 0) return; GC_err_printf0("GC_check_heap_block: found smashed heap objects:\n"); for (i = 0; i < GC_n_smashed; ++i) { GC_print_smashed_obj(GC_base(GC_smashed[i]), GC_smashed[i]); GC_smashed[i] = 0; } GC_n_smashed = 0;}/* Check all marked objects in the given block for validity *//*ARGSUSED*/# if defined(__STDC__) || defined(__cplusplus) void GC_check_heap_block(register struct hblk *hbp, word dummy)# else void GC_check_heap_block(hbp, dummy) register struct hblk *hbp; /* ptr to current heap block */ word dummy;# endif{ register struct hblkhdr * hhdr = HDR(hbp); register word sz = hhdr -> hb_sz; register int word_no; register word *p, *plim; p = (word *)(hbp->hb_body); word_no = 0; if (sz > MAXOBJSZ) { plim = p; } else { plim = (word *)((((word)hbp) + HBLKSIZE) - WORDS_TO_BYTES(sz)); } /* go through all words in block */ while( p <= plim ) { if( mark_bit_from_hdr(hhdr, word_no) && GC_HAS_DEBUG_INFO((ptr_t)p)) { ptr_t clobbered = GC_check_annotated_obj((oh *)p); if (clobbered != 0) GC_add_smashed(clobbered); } word_no += sz; p += sz; }}/* This assumes that all accessible objects are marked, and that *//* I hold the allocation lock. Normally called by collector. */void GC_check_heap_proc(){# ifndef SMALL_CONFIG# ifdef ALIGN_DOUBLE GC_STATIC_ASSERT((sizeof(oh) & (2 * sizeof(word) - 1)) == 0);# else GC_STATIC_ASSERT((sizeof(oh) & (sizeof(word) - 1)) == 0);# endif# endif GC_apply_to_all_blocks(GC_check_heap_block, (word)0);}#endif /* !SHORT_DBG_HDRS */struct closure { GC_finalization_proc cl_fn; GC_PTR cl_data;};# ifdef __STDC__ void * GC_make_closure(GC_finalization_proc fn, void * data)# else GC_PTR GC_make_closure(fn, data) GC_finalization_proc fn; GC_PTR data;# endif{ struct closure * result =# ifdef DBG_HDRS_ALL (struct closure *) GC_debug_malloc(sizeof (struct closure), GC_EXTRAS);# else (struct closure *) GC_malloc(sizeof (struct closure));# endif result -> cl_fn = fn; result -> cl_data = data; return((GC_PTR)result);}# ifdef __STDC__ void GC_debug_invoke_finalizer(void * obj, void * data)# else void GC_debug_invoke_finalizer(obj, data) char * obj; char * data;# endif{ register struct closure * cl = (struct closure *) data; (*(cl -> cl_fn))((GC_PTR)((char *)obj + sizeof(oh)), cl -> cl_data);} /* Set ofn and ocd to reflect the values we got back. */static void store_old (obj, my_old_fn, my_old_cd, ofn, ocd)GC_PTR obj;GC_finalization_proc my_old_fn;struct closure * my_old_cd;GC_finalization_proc *ofn;GC_PTR *ocd;{ if (0 != my_old_fn) { if (my_old_fn != GC_debug_invoke_finalizer) { GC_err_printf1("Debuggable object at 0x%lx had non-debug finalizer.\n", obj); /* This should probably be fatal. */ } else { if (ofn) *ofn = my_old_cd -> cl_fn; if (ocd) *ocd = my_old_cd -> cl_data; } } else { if (ofn) *ofn = 0; if (ocd) *ocd = 0; }}# ifdef __STDC__ void GC_debug_register_finalizer(GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, GC_finalization_proc *ofn, GC_PTR *ocd)# else void GC_debug_register_finalizer(obj, fn, cd, ofn, ocd) GC_PTR obj; GC_finalization_proc fn; GC_PTR cd; GC_finalization_proc *ofn; GC_PTR *ocd;# endif{ GC_finalization_proc my_old_fn; GC_PTR my_old_cd; ptr_t base = GC_base(obj); if (0 == base) return; if ((ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_debug_register_finalizer called with non-base-pointer 0x%lx\n", obj); } if (0 == fn) { GC_register_finalizer(base, 0, 0, &my_old_fn, &my_old_cd); } else { GC_register_finalizer(base, GC_debug_invoke_finalizer, GC_make_closure(fn,cd), &my_old_fn, &my_old_cd); } store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);}# ifdef __STDC__ void GC_debug_register_finalizer_no_order (GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, GC_finalization_proc *ofn, GC_PTR *ocd)# else void GC_debug_register_finalizer_no_order (obj, fn, cd, ofn, ocd) GC_PTR obj; GC_finalization_proc fn; GC_PTR cd; GC_finalization_proc *ofn; GC_PTR *ocd;# endif{ GC_finalization_proc my_old_fn; GC_PTR my_old_cd; ptr_t base = GC_base(obj); if (0 == base) return; if ((ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_debug_register_finalizer_no_order called with non-base-pointer 0x%lx\n", obj); } if (0 == fn) { GC_register_finalizer_no_order(base, 0, 0, &my_old_fn, &my_old_cd); } else { GC_register_finalizer_no_order(base, GC_debug_invoke_finalizer, GC_make_closure(fn,cd), &my_old_fn, &my_old_cd); } store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd); }# ifdef __STDC__ void GC_debug_register_finalizer_ignore_self (GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, GC_finalization_proc *ofn, GC_PTR *ocd)# else void GC_debug_register_finalizer_ignore_self (obj, fn, cd, ofn, ocd) GC_PTR obj; GC_finalization_proc fn; GC_PTR cd; GC_finalization_proc *ofn; GC_PTR *ocd;# endif{ GC_finalization_proc my_old_fn; GC_PTR my_old_cd; ptr_t base = GC_base(obj); if (0 == base) return; if ((ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_debug_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n", obj); } if (0 == fn) { GC_register_finalizer_ignore_self(base, 0, 0, &my_old_fn, &my_old_cd); } else { GC_register_finalizer_ignore_self(base, GC_debug_invoke_finalizer, GC_make_closure(fn,cd), &my_old_fn, &my_old_cd); } store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);}#ifdef GC_ADD_CALLER# define RA GC_RETURN_ADDR,#else# define RA#endifGC_PTR GC_debug_malloc_replacement(lb)size_t lb;{ return GC_debug_malloc(lb, RA "unknown", 0);}GC_PTR GC_debug_realloc_replacement(p, lb)GC_PTR p;size_t lb;{ return GC_debug_realloc(p, lb, RA "unknown", 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -