If a type has a repr function but no print function, printing it now

calls the repr function.  When the refcount is bad, don't print
the object at all (chances of crashes).
Changes to checking and printing of references: the consistency
check is somewhat faster; don't print strings referenced once
(most occur in function's name lists).
This commit is contained in:
Guido van Rossum 1992-09-03 20:32:55 +00:00
parent 99bec95482
commit 2e8f6140ff
1 changed files with 34 additions and 5 deletions

View File

@ -77,10 +77,28 @@ printobject(op, fp, flags)
} }
else { else {
if (op->ob_refcnt <= 0) if (op->ob_refcnt <= 0)
fprintf(fp, "(refcnt %u):", op->ob_refcnt); fprintf(fp, "<refcnt %u at %lx>",
if (op->ob_type->tp_print == NULL) op->ob_refcnt, (long)op);
else if (op->ob_type->tp_print == NULL) {
if (op->ob_type->tp_repr == NULL) {
fprintf(fp, "<%s object at %lx>", fprintf(fp, "<%s object at %lx>",
op->ob_type->tp_name, (long)op); op->ob_type->tp_name, (long)op);
}
else {
object *s = reprobject(op);
if (s == NULL)
ret = -1;
else if (!is_stringobject(s)) {
err_setstr(TypeError,
"repr not string");
ret = -1;
}
else {
fprintf(fp, "%s", getstringvalue(s));
}
XDECREF(s);
}
}
else else
ret = (*op->ob_type->tp_print)(op, fp, flags); ret = (*op->ob_type->tp_print)(op, fp, flags);
} }
@ -252,6 +270,12 @@ UNREF(op)
fprintf(stderr, "UNREF negative refcnt\n"); fprintf(stderr, "UNREF negative refcnt\n");
abort(); abort();
} }
if (op == &refchain ||
op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
fprintf(stderr, "UNREF invalid object\n");
abort();
}
#ifdef SLOW_UNREF_CHECK
for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) { for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
if (p == op) if (p == op)
break; break;
@ -260,8 +284,10 @@ UNREF(op)
fprintf(stderr, "UNREF unknown object\n"); fprintf(stderr, "UNREF unknown object\n");
abort(); abort();
} }
#endif
op->_ob_next->_ob_prev = op->_ob_prev; op->_ob_next->_ob_prev = op->_ob_prev;
op->_ob_prev->_ob_next = op->_ob_next; op->_ob_prev->_ob_next = op->_ob_next;
op->_ob_next = op->_ob_prev = NULL;
} }
DELREF(op) DELREF(op)
@ -269,14 +295,17 @@ DELREF(op)
{ {
UNREF(op); UNREF(op);
(*(op)->ob_type->tp_dealloc)(op); (*(op)->ob_type->tp_dealloc)(op);
op->ob_type = NULL;
} }
printrefs(fp) printrefs(fp)
FILE *fp; FILE *fp;
{ {
object *op; object *op;
fprintf(fp, "Remaining objects:\n"); fprintf(fp, "Remaining objects (except strings referenced once):\n");
for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
if (op->ob_refcnt == 1 && is_stringobject(op))
continue; /* Will be printed elsewhere */
fprintf(fp, "[%d] ", op->ob_refcnt); fprintf(fp, "[%d] ", op->ob_refcnt);
if (printobject(op, fp, 0) != 0) if (printobject(op, fp, 0) != 0)
err_clear(); err_clear();