plpython tracebacks

From: "P(dot) Scott DeVos" <scott(at)countrysidetechnology(dot)com>
To: pgsql-patches(at)postgresql(dot)org
Subject: plpython tracebacks
Date: 2006-02-06 22:05:37
Message-ID: 43E7C831.3050207@countrysidetechnology.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

I have been working with plpython for several months and have
been hampered by the lack of a traceback being logged when a
plpython function raises an error. I have written a patch causes
the PLy_traceback function to fully log the traceback. The
output looks just like the traceback output provided by the
python interpreter.

Feedback appreciated.

Scott

--- plpython-1.70.c.orig 2006-02-06 14:24:42.000000000 -0600
+++ plpython-1.70.c.patched 2006-02-06 15:34:05.000000000 -0600
@@ -2499,7 +2499,8 @@
*vob = NULL;
char *vstr,
*estr,
- *xstr = NULL;
+ *xstr = NULL,
+ *tbstr;

/*
* get the current exception
@@ -2523,6 +2524,82 @@
else
vstr = "Unknown";

+ /* If there is a traceback object, we build a string containing
+ the traceback information. */
+ if (tb != NULL)
+ {
+ PyObject
+ *cur_tb, /* traceback (tb) item being handled */
+ *old_tb, /* holds tb so we can decrement reference to it */
+ *hdr, /* First line of logged output */
+ *tmpl, /* PyString template for the logged tb item */
+ *ftr, /* Last line of logged output */
+ *tb_list, /* Each tb item create a PyString in this list */
+ *ln, /* The line number of the item in the traceback */
+ *frame, /* the tb_frame */
+ *code, /* the f_code this guy has filename and method name*/
+ *fn, /* the filename of the item in the tb */
+ *nm, /* the function/method name of the item in the tb */
+ *args, /* A tuple of the form (fn, ln, nm) */
+ *logline, /* The assembled string with the logged message */
+ *os, /* points to the os module */
+ *sep, /* line separator */
+ *tb_log; /* PyString with the assembled log msg */
+
+ hdr = PyString_FromString("Traceback (most recent call last):");
+ tmpl = PyString_FromString(" File \"%s\", line %s, in %s");
+ ftr = PyString_FromString("");
+
+ tb_list = PyList_New(0); /* create the list of strings */
+ PyList_Append(tb_list, hdr); /* Append the header to the list */
+
+ /* 1st tb is useless; throw it away */
+ cur_tb = PyObject_GetAttrString(tb, "tb_next");
+ while (cur_tb != Py_None)
+ {
+
+ ln = PyObject_GetAttrString(cur_tb, "tb_lineno");
+ frame = PyObject_GetAttrString(cur_tb, "tb_frame");
+ code = PyObject_GetAttrString(frame, "f_code");
+ fn = PyObject_GetAttrString(code, "co_filename");
+ nm = PyObject_GetAttrString(code, "co_name");
+
+ args = Py_BuildValue("(OOO)", fn, ln, nm); /* args tuple */
+ logline = PyString_Format(tmpl, args); /* build logged string */
+ PyList_Append(tb_list, logline); /* append string to list */
+
+ /* decrement references on all our objects */
+ Py_DECREF(logline);
+ Py_DECREF(args);
+ Py_XDECREF(nm);
+ Py_XDECREF(fn);
+ Py_XDECREF(code);
+ Py_XDECREF(frame);
+ Py_XDECREF(ln);
+
+ old_tb = cur_tb;
+ /* get the next traceback item */
+ cur_tb = PyObject_GetAttrString(cur_tb, "tb_next");
+ Py_DECREF(old_tb); /* we're done with old_tb so decref it */
+ }
+ PyList_Append(tb_list, ftr); /* append the log msg footer */
+
+ os = PyImport_ImportModule("os");
+ sep = PyObject_GetAttrString(os, "linesep"); /* get os EOL char */
+ tb_log = _PyString_Join(sep, tb_list); /* create tb log msgs */
+ tbstr = PyString_AsString(tb_log);
+
+ Py_DECREF(tb_log);
+ Py_DECREF(sep);
+ Py_DECREF(os);
+ Py_DECREF(tb_list);
+ Py_DECREF(ftr);
+ Py_DECREF(tmpl);
+ Py_DECREF(hdr);
+ }
+ else
+ tbstr = "No Traceback";
+
/*
* I'm not sure what to do if eob is NULL here -- we can't call PLy_elog
* because that function calls us, so we could end up with infinite
@@ -2530,7 +2607,7 @@
* Assert() be more appropriate?
*/
estr = eob ? PyString_AsString(eob) : "Unknown Exception";
- xstr = PLy_printf("%s: %s", estr, vstr);
+ xstr = PLy_printf("%s%s: %s", tbstr, estr, vstr);

Py_DECREF(eob);
Py_XDECREF(vob);

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Thomas F. O'Connell 2006-02-06 23:56:45 Re: pgbench: Support Multiple Simultaneous Runs (with Mean and Std. Dev.)
Previous Message Michael Meskes 2006-02-06 20:33:16 Re: [BUGS] BUG #2171: Differences compiling plpgsql in ecpg and psql