diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index 9352580..b2333b8 100644 *** a/src/pl/plpython/plpython.c --- b/src/pl/plpython/plpython.c *************** get_source_line(const char *src, int lin *** 4507,4512 **** --- 4507,4520 ---- if (next == NULL) return pstrdup(s); + /* + * Sanity check, next < s if the line was all-whitespace, which should + * never happen if Python reported an frame created on that line, but + * check anyway. + */ + if (next < s) + return NULL; + return pnstrdup(s, next - s); } *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4603,4608 **** --- 4611,4617 ---- PyObject *volatile code = NULL; PyObject *volatile name = NULL; PyObject *volatile lineno = NULL; + PyObject *volatile filename = NULL; PG_TRY(); { *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4621,4626 **** --- 4630,4639 ---- name = PyObject_GetAttrString(code, "co_name"); if (name == NULL) elog(ERROR, "could not get function name from Python code object"); + + filename = PyObject_GetAttrString(code, "co_filename"); + if (filename == NULL) + elog(ERROR, "could not get file name from Python code object"); } PG_CATCH(); { *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4628,4633 **** --- 4641,4647 ---- Py_XDECREF(code); Py_XDECREF(name); Py_XDECREF(lineno); + Py_XDECREF(filename); PG_RE_THROW(); } PG_END_TRY(); *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4638,4643 **** --- 4652,4658 ---- char *proname; char *fname; char *line; + char *plain_filename; long plain_lineno; /* *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4651,4656 **** --- 4666,4672 ---- fname = PyString_AsString(name); proname = PLy_procedure_name(PLy_curr_procedure); + plain_filename = PyString_AsString(filename); plain_lineno = PyInt_AsLong(lineno); if (proname == NULL) *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4662,4668 **** &tbstr, "\n PL/Python function \"%s\", line %ld, in %s", proname, plain_lineno - 1, fname); ! if (PLy_curr_procedure) { /* * If we know the current procedure, append the exact --- 4678,4686 ---- &tbstr, "\n PL/Python function \"%s\", line %ld, in %s", proname, plain_lineno - 1, fname); ! /* the code object was compiled with "" as the filename */ ! if (PLy_curr_procedure && plain_filename != NULL && ! strcmp(plain_filename, "") == 0) { /* * If we know the current procedure, append the exact *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4670,4676 **** * traceback.py module behavior. We could store the * already line-split source to avoid splitting it * every time, but producing a traceback is not the ! * most important scenario to optimize for. */ line = get_source_line(PLy_curr_procedure->src, plain_lineno); if (line) --- 4688,4696 ---- * traceback.py module behavior. We could store the * already line-split source to avoid splitting it * every time, but producing a traceback is not the ! * most important scenario to optimize for. However, ! * do not go as far as traceback.py in reading the source ! * of imported modules. */ line = get_source_line(PLy_curr_procedure->src, plain_lineno); if (line) *************** PLy_traceback(char **xmsg, char **tbmsg, *** 4685,4690 **** --- 4705,4711 ---- Py_DECREF(code); Py_DECREF(name); Py_DECREF(lineno); + Py_DECREF(filename); /* Release the current frame and go to the next one. */ tb_prev = tb;