Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(123)

Unified Diff: Modules/gcmodule.c

Issue 110078: Add a stream parameter to gc.set_debug Base URL: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: do not rely on FILE* for py3k; doc fix Created 15 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Misc/NEWS ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Modules/gcmodule.c
===================================================================
--- Modules/gcmodule.c (revision 74542)
+++ Modules/gcmodule.c (working copy)
@@ -127,6 +127,12 @@
static int debug;
static PyObject *tmod = NULL;
+/*
+ Defines where debugging output is written.
+ Should be a write(str) callable. If NULL, output is written to stderr.
+*/
+static PyObject* debug_writer = NULL;
+
/*--------------------------------------------------------------------------
gc_refs values.
@@ -689,6 +695,25 @@
}
static void
+debug_print(const char* format, ...)
+{
+ va_list va;
+
+ va_start(va, format);
+
+ if (debug_writer == NULL) PySys_WriteStderr(format, va);
+ else {
+
+ PyObject* msg = PyString_FromFormatV(format, va);
+ if (NULL == PyObject_CallFunctionObjArgs(debug_writer, msg, NULL))
+ PyErr_WriteUnraisable(debug_writer);
+
+ Py_DECREF(msg);
+ }
+ va_end(va);
+}
+
+static void
debug_instance(char *msg, PyInstanceObject *inst)
{
char *cname;
@@ -698,7 +723,7 @@
cname = PyString_AsString(classname);
else
cname = "?";
- PySys_WriteStderr("gc: %.100s <%.100s instance at %p>\n",
+ debug_print("gc: %.100s <%.100s instance at %p>\n",
msg, cname, inst);
}
@@ -709,7 +734,7 @@
debug_instance(msg, (PyInstanceObject *)op);
}
else if (debug & DEBUG_OBJECTS) {
- PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
+ debug_print("gc: %.100s <%.100s %p>\n",
msg, Py_TYPE(op)->tp_name, op);
}
}
@@ -838,13 +863,13 @@
if (debug & DEBUG_STATS) {
t1 = get_time();
- PySys_WriteStderr("gc: collecting generation %d...\n",
+ debug_print("gc: collecting generation %d...\n",
generation);
- PySys_WriteStderr("gc: objects in each generation:");
+ debug_print("gc: objects in each generation:");
for (i = 0; i < NUM_GENERATIONS; i++)
- PySys_WriteStderr(" %" PY_FORMAT_SIZE_T "d",
+ debug_print(" %" PY_FORMAT_SIZE_T "d",
gc_list_size(GEN_HEAD(i)));
- PySys_WriteStderr("\n");
+ debug_print("\n");
}
/* update collection and allocation counters */
@@ -941,17 +966,17 @@
if (debug & DEBUG_STATS) {
double t2 = get_time();
if (m == 0 && n == 0)
- PySys_WriteStderr("gc: done");
+ debug_print("gc: done");
else
- PySys_WriteStderr(
+ debug_print(
"gc: done, "
"%" PY_FORMAT_SIZE_T "d unreachable, "
"%" PY_FORMAT_SIZE_T "d uncollectable",
n+m, n);
if (t1 && t2) {
- PySys_WriteStderr(", %.4fs elapsed", t2-t1);
+ debug_print(", %.4fs elapsed", t2-t1);
}
- PySys_WriteStderr(".\n");
+ debug_print(".\n");
}
/* Append instances in the uncollectable set to a Python
@@ -1072,7 +1097,7 @@
}
PyDoc_STRVAR(gc_set_debug__doc__,
-"set_debug(flags) -> None\n"
+"set_debug(flags[, stream=sys.stderr]) -> None\n"
"\n"
"Set the garbage collection debugging flags. Debugging information is\n"
"written to sys.stderr.\n"
@@ -1085,14 +1110,41 @@
" DEBUG_INSTANCES - Print instance objects.\n"
" DEBUG_OBJECTS - Print objects other than instances.\n"
" DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n"
-" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n");
+" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n"
+"\n"
+"stream is a file object to which debugging output will be written.\n");
static PyObject *
gc_set_debug(PyObject *self, PyObject *args)
{
- if (!PyArg_ParseTuple(args, "i:set_debug", &debug))
+ PyObject* stream = NULL;
+ int flags;
+
+ if (!PyArg_ParseTuple(args, "i|O:set_debug", &flags, &stream))
return NULL;
+ PyObject* writer = NULL;
+ if (stream != NULL) {
+ /* Be defensive, we don't want errors to occur during collection */
+ writer = PyObject_GetAttrString(stream, "write");
+ if (writer == NULL)
+ return NULL;
+
+ if (!PyCallable_Check(writer)) {
+ PyErr_SetString(PyExc_TypeError,
+ "attribute write of parameter stream must be callable");
+ return NULL;
+ }
+
+ }
+
+ if (debug_writer != NULL) {
+ Py_DECREF(debug_writer);
+ debug_writer = NULL;
+ }
+ debug_writer = writer;
+ debug = flags;
+
Py_INCREF(Py_None);
return Py_None;
}
« no previous file with comments | « Misc/NEWS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b