summaryrefslogtreecommitdiff
path: root/dbg_mlc.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2011-07-26 15:08:53 +0200
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 15:08:53 +0200
commitf3632431e72d48bc7772b0752e29bb1e2a0901c6 (patch)
treed4451ec3ef902e734e16d601d191e1497fba7fc1 /dbg_mlc.c
parent3313dcc53de4d5d5f76f58a856beb06688d1f8c7 (diff)
gc6.1 tarball importgc6_1
Diffstat (limited to 'dbg_mlc.c')
-rw-r--r--dbg_mlc.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/dbg_mlc.c b/dbg_mlc.c
index 1e5aaba..a67fef2 100644
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -228,6 +228,8 @@ ptr_t p;
#endif /* KEEP_BACK_PTRS */
+# define CROSSES_HBLK(p, sz) \
+ (((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE)
/* Store debugging info into p. Return displaced pointer. */
/* Assumes we don't hold allocation lock. */
ptr_t GC_store_debug_info(p, sz, string, integer)
@@ -243,6 +245,8 @@ word integer;
/* But that's expensive. And this way things should only appear */
/* inconsistent while we're in the handler. */
LOCK();
+ GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
+ GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
# ifdef KEEP_BACK_PTRS
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
# endif
@@ -275,6 +279,8 @@ word integer;
/* There is some argument that we should disable signals here. */
/* But that's expensive. And this way things should only appear */
/* inconsistent while we're in the handler. */
+ GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
+ GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
# ifdef KEEP_BACK_PTRS
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
# endif
@@ -324,6 +330,7 @@ ptr_t p;
{
register oh * ohdr = (oh *)GC_base(p);
+ GC_ASSERT(!I_HOLD_LOCK());
GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh)));
GC_err_puts(ohdr -> oh_string);
# ifdef SHORT_DBG_HDRS
@@ -342,6 +349,7 @@ ptr_t p;
ptr_t p;
# endif
{
+ GC_ASSERT(!I_HOLD_LOCK());
if (GC_HAS_DEBUG_INFO(p)) {
GC_print_obj(p);
} else {
@@ -355,6 +363,7 @@ ptr_t p, clobbered_addr;
{
register oh * ohdr = (oh *)GC_base(p);
+ GC_ASSERT(!I_HOLD_LOCK());
GC_err_printf2("0x%lx in object at 0x%lx(", (unsigned long)clobbered_addr,
(unsigned long)p);
if (clobbered_addr <= (ptr_t)(&(ohdr -> oh_sz))
@@ -376,14 +385,18 @@ ptr_t p, clobbered_addr;
void GC_check_heap_proc GC_PROTO((void));
+void GC_print_all_smashed_proc GC_PROTO((void));
+
void GC_do_nothing() {}
void GC_start_debugging()
{
# ifndef SHORT_DBG_HDRS
GC_check_heap = GC_check_heap_proc;
+ GC_print_all_smashed = GC_print_all_smashed_proc;
# else
GC_check_heap = GC_do_nothing;
+ GC_print_all_smashed = GC_do_nothing;
# endif
GC_print_heap_obj = GC_debug_print_heap_obj_proc;
GC_debugging_started = TRUE;
@@ -775,6 +788,45 @@ void GC_debug_free_inner(GC_PTR p)
}
#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 20
+ptr_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)
@@ -803,11 +855,7 @@ void GC_debug_free_inner(GC_PTR p)
&& GC_HAS_DEBUG_INFO((ptr_t)p)) {
ptr_t clobbered = GC_check_annotated_obj((oh *)p);
- if (clobbered != 0) {
- GC_err_printf0(
- "GC_check_heap_block: found smashed location at ");
- GC_print_smashed_obj((ptr_t)p, clobbered);
- }
+ if (clobbered != 0) GC_add_smashed(clobbered);
}
word_no += sz;
p += sz;