2008-05-13
2008-05-13 19:03:59 by Martin Stjernholm <mast@lysator.liu.se>
-
e30c81f6c1f544062cfc6e2ef50b3b3cf9598650
(80 lines)
(+70/-10)
[
Show
| Annotate
]
Branch: 7.9
More debug to try to nail a bug with the cycle rec stack.
Rev: src/gc.c:1.315
2:
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: gc.c,v 1.314 2008/05/11 16:57:37 mast Exp $
+ || $Id: gc.c,v 1.315 2008/05/13 19:03:59 mast Exp $
*/
#include "global.h"
161:
};
/* rf_flags bits. */
- #define GC_PREV_WEAK 0x01
- #define GC_PREV_STRONG 0x02
- #define GC_PREV_BROKEN 0x04
- #define GC_MARK_LIVE 0x08
- #define GC_ON_KILL_LIST 0x10
+ #define GC_PREV_WEAK 0x0001
+ #define GC_PREV_STRONG 0x0002
+ #define GC_PREV_BROKEN 0x0004
+ #define GC_MARK_LIVE 0x0008
+ #define GC_ON_KILL_LIST 0x0010
#ifdef PIKE_DEBUG
- #define GC_ON_CYCLE_PIECE_LIST 0x20
- #define GC_FRAME_FREED 0x40
- #define GC_FOLLOWED_NONSTRONG 0x80
+ #define GC_ON_CYCLE_PIECE_LIST 0x0020
+ #define GC_FRAME_FREED 0x0040
+ #define GC_FOLLOWED_NONSTRONG 0x0080
+ #define GC_IS_VALID_CP_CYCLE_ID 0x0100
#endif
static struct gc_rec_frame sentinel_frame = {
564: Inside #if defined (PIKE_DEBUG) || defined (GC_CYCLE_DEBUG)
struct gc_rec_frame *p2, const char *p2_name,
struct gc_rec_frame *p3, const char *p3_name)
{
- struct gc_rec_frame *l;
+ struct gc_rec_frame *l, *cp;
size_t longest;
-
+
if (p1) longest = strlen (p1_name);
if (p2) {size_t l = strlen (p2_name); if (l > longest) longest = l;}
if (p3) {size_t l = strlen (p3_name); if (l > longest) longest = l;}
longest++;
-
+
+ /* Note: Stack is listed from top to bottom, but cycle piece lists
+ * are lists from first to last, i.e. reverse order. */
+
for (l = stack_top; l != &sentinel_frame; l = l->prev) {
size_t c = 0;
-
+
if (!l) {fputs (" <broken prev link in rec stack>\n", stderr); break;}
fprintf (stderr, " %p", l);
-
+
if (l == p1) {fprintf (stderr, " %s", p1_name); c += strlen (p1_name) + 1;}
if (l == p2) {fprintf (stderr, " %s", p2_name); c += strlen (p2_name) + 1;}
if (l == p3) {fprintf (stderr, " %s", p3_name); c += strlen (p3_name) + 1;}
fprintf (stderr, ": %*s", c < longest ? (int) (longest - c) : 0, "");
-
+
describe_rec_frame (l);
fputc ('\n', stderr);
-
+
+ for (cp = l->cycle_piece; cp; cp = cp->cycle_piece) {
+ fprintf (stderr, " %p", cp);
+
+ c = 0;
+ if (cp == p1) {fprintf (stderr, " %s", p1_name); c += strlen (p1_name)+1;}
+ if (cp == p2) {fprintf (stderr, " %s", p2_name); c += strlen (p2_name)+1;}
+ if (cp == p3) {fprintf (stderr, " %s", p3_name); c += strlen (p3_name)+1;}
+ fprintf (stderr, ": %*s", c < longest ? (int) (longest - c) : 0, "");
+
+ describe_rec_frame (cp);
+ fputc ('\n', stderr);
}
}
-
+ }
#endif
2246:
else if (l->rf_flags & GC_PREV_WEAK)
rec_stack_fatal (l, "err", p1, p1n, p2, p2n, file, line,
"Unexpected weak ref before %p inside a cycle.\n", l);
+
+ if (l->rf_flags & GC_IS_VALID_CP_CYCLE_ID)
+ rec_stack_fatal (l, "err", p1, p1n, p2, p2n, file, line,
+ "Frame %p got stray "
+ "GC_IS_VALID_CP_CYCLE_ID flag.\n", l);
+ if (l->cycle_piece) {
+ struct gc_rec_frame *cp = l->cycle_piece;
+ l->rf_flags |= GC_IS_VALID_CP_CYCLE_ID;
+
+ while (1) {
+ if (!cp->cycle_id ||
+ !(cp->cycle_id->rf_flags & GC_IS_VALID_CP_CYCLE_ID))
+ rec_stack_fatal (cp, "err", p1, p1n, p2, p2n, file, line,
+ "Unexpected cycle id for frame %p "
+ "on cycle piece list.\n", cp);
+ if (cp->rf_flags & GC_IS_VALID_CP_CYCLE_ID)
+ rec_stack_fatal (cp, "err", p1, p1n, p2, p2n, file, line,
+ "Frame %p got stray "
+ "GC_IS_VALID_CP_CYCLE_ID flag.\n", cp);
+ cp->rf_flags |= GC_IS_VALID_CP_CYCLE_ID;
+ check_cycle_piece_frame (cp, file, line);
+ if (!cp->cycle_piece) break;
+ cp = cp->cycle_piece;
}
-
+
+ if (l->cycle_piece->u.last_cycle_piece != cp)
+ rec_stack_fatal (l->cycle_piece, "err", p1, p1n, p2, p2n, file, line,
+ "last_cycle_piece is wrong for frame %p, "
+ "expected %p.\n", l->cycle_piece, cp);
+
+ l->rf_flags &= ~GC_IS_VALID_CP_CYCLE_ID;
+ cp = l->cycle_piece;
+ do {
+ cp->rf_flags &= ~GC_IS_VALID_CP_CYCLE_ID;
+ cp = cp->cycle_piece;
+ } while (cp);
}
}
-
+ }
+ }
#define CHECK_REC_STACK(p1, p1n, p2, p2n) \
do check_rec_stack ((p1), (p1n), (p2), (p2n), __FILE__, __LINE__); while (0)