/* * A little helper to dump pythons last error info either to file only or * additional popup a message_error */ void _pyerror_report_last (gboolean popup, const char* fn, const char* file, int line) { PyObject *exc, *v, *tb, *ef; char* sLoc; if (strlen(fn) > 0) sLoc = g_strdup_printf ("PyDia Error (%s):\n", fn); /* GNU_PRETTY_FUNCTION is enough */ else sLoc = g_strdup_printf ("PyDia Error (%s:%d):\n", file, line); PyErr_Fetch (&exc, &v, &tb); PyErr_NormalizeException(&exc, &v, &tb); ef = PyDiaError_New(sLoc, popup ? FALSE : TRUE); PyFile_WriteObject (exc, ef, 0); PyFile_WriteObject (v, ef, 0); PyTraceBack_Print(tb, ef); if (((PyDiaError*)ef)->str && popup) message_error ("%s", ((PyDiaError*)ef)->str->str); g_free (sLoc); Py_DECREF (ef); Py_XDECREF(exc); Py_XDECREF(v); Py_XDECREF(tb); }
/* To test the format of tracebacks as printed out. */ static PyObject * traceback_print(PyObject *self, PyObject *args) { PyObject *file; PyObject *traceback; int result; if (!PyArg_ParseTuple(args, "OO:traceback_print", &traceback, &file)) return NULL; result = PyTraceBack_Print(traceback, file); if (result < 0) return NULL; Py_RETURN_NONE; }
/* Call when an exception has occurred but there is no way for Python to handle it. Examples: exception in __del__ or during GC. */ void PyErr_WriteUnraisable(PyObject *obj) { _Py_IDENTIFIER(__module__); PyObject *f, *t, *v, *tb; PyObject *moduleName = NULL; char* className; PyErr_Fetch(&t, &v, &tb); f = _PySys_GetObjectId(&PyId_stderr); if (f == NULL || f == Py_None) goto done; if (obj) { if (PyFile_WriteString("Exception ignored in: ", f) < 0) goto done; if (PyFile_WriteObject(obj, f, 0) < 0) { PyErr_Clear(); if (PyFile_WriteString("<object repr() failed>", f) < 0) { goto done; } } if (PyFile_WriteString("\n", f) < 0) goto done; } if (PyTraceBack_Print(tb, f) < 0) goto done; if (!t) goto done; assert(PyExceptionClass_Check(t)); className = PyExceptionClass_Name(t); if (className != NULL) { char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = _PyObject_GetAttrId(t, &PyId___module__); if (moduleName == NULL) { PyErr_Clear(); if (PyFile_WriteString("<unknown>", f) < 0) goto done; } else { if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { if (PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) < 0) goto done; if (PyFile_WriteString(".", f) < 0) goto done; } } if (className == NULL) { if (PyFile_WriteString("<unknown>", f) < 0) goto done; } else { if (PyFile_WriteString(className, f) < 0) goto done; } if (v && v != Py_None) { if (PyFile_WriteString(": ", f) < 0) goto done; if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) { PyErr_Clear(); if (PyFile_WriteString("<exception str() failed>", f) < 0) { goto done; } } } if (PyFile_WriteString("\n", f) < 0) goto done; done: Py_XDECREF(moduleName); Py_XDECREF(t); Py_XDECREF(v); Py_XDECREF(tb); PyErr_Clear(); /* Just in case */ }
void PyErr_PrintEx(int set_sys_last_vars) { int err = 0; PyObject *exception, *v, *tb, *f; PyErr_Fetch(&exception, &v, &tb); PyErr_NormalizeException(&exception, &v, &tb); if (exception == NULL) return; if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) { if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); if (v == NULL || v == Py_None) Py_Exit(0); if (PyInstance_Check(v)) { /* we expect the error code to be store in the `code' attribute */ PyObject *code = PyObject_GetAttrString(v, "code"); if (code) { Py_DECREF(v); v = code; if (v == Py_None) Py_Exit(0); } /* if we failed to dig out the "code" attribute, then just let the else clause below print the error */ } if (PyInt_Check(v)) Py_Exit((int)PyInt_AsLong(v)); else { /* OK to use real stderr here */ PyObject_Print(v, stderr, Py_PRINT_RAW); fprintf(stderr, "\n"); Py_Exit(1); } } if (set_sys_last_vars) { PySys_SetObject("last_type", exception); PySys_SetObject("last_value", v); PySys_SetObject("last_traceback", tb); } f = PySys_GetObject("stderr"); if (f == NULL) fprintf(stderr, "lost sys.stderr\n"); else { if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); err = PyTraceBack_Print(tb, f); if (err == 0 && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) { PyObject *message; char *filename, *text; int lineno, offset; if (!parse_syntax_error(v, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); else { char buf[10]; PyFile_WriteString(" File \"", f); if (filename == NULL) PyFile_WriteString("<string>", f); else PyFile_WriteString(filename, f); PyFile_WriteString("\", line ", f); sprintf(buf, "%d", lineno); PyFile_WriteString(buf, f); PyFile_WriteString("\n", f); if (text != NULL) { char *nl; if (offset > 0 && offset == (int)strlen(text)) offset--; for (;;) { nl = strchr(text, '\n'); if (nl == NULL || nl-text >= offset) break; offset -= (nl+1-text); text = nl+1; } while (*text == ' ' || *text == '\t') { text++; offset--; } PyFile_WriteString(" ", f); PyFile_WriteString(text, f); if (*text == '\0' || text[strlen(text)-1] != '\n') PyFile_WriteString("\n", f); PyFile_WriteString(" ", f); offset--; while (offset > 0) { PyFile_WriteString(" ", f); offset--; } PyFile_WriteString("^\n", f); } Py_INCREF(message); Py_DECREF(v); v = message; /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) err = -1; } } if (err) { /* Don't do anything else */ } else if (PyClass_Check(exception)) { PyClassObject* exc = (PyClassObject*)exception; PyObject* className = exc->cl_name; PyObject* moduleName = PyDict_GetItemString(exc->cl_dict, "__module__"); if (moduleName == NULL) err = PyFile_WriteString("<unknown>", f); else { char* modstr = PyString_AsString(moduleName); if (modstr && strcmp(modstr, "exceptions")) { err = PyFile_WriteString(modstr, f); err += PyFile_WriteString(".", f); } } if (err == 0) { if (className == NULL) err = PyFile_WriteString("<unknown>", f); else err = PyFile_WriteObject(className, f, Py_PRINT_RAW); } } else err = PyFile_WriteObject(exception, f, Py_PRINT_RAW); if (err == 0) { if (v != NULL && v != Py_None) { PyObject *s = PyObject_Str(v); /* only print colon if the str() of the object is not the empty string */ if (s == NULL) err = -1; else if (!PyString_Check(s) || PyString_GET_SIZE(s) != 0) err = PyFile_WriteString(": ", f); if (err == 0) err = PyFile_WriteObject(s, f, Py_PRINT_RAW); Py_XDECREF(s); } } if (err == 0) err = PyFile_WriteString("\n", f); } Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) PyErr_Clear(); }
static void print_exception(PyObject *f, PyObject *value) { int err = 0; PyObject *type, *tb; _Py_IDENTIFIER(print_file_and_line); if (!PyExceptionInstance_Check(value)) { err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); err += PyFile_WriteString(Py_TYPE(value)->tp_name, f); err += PyFile_WriteString(" found\n", f); if (err) PyErr_Clear(); return; } Py_INCREF(value); fflush(stdout); type = (PyObject *) Py_TYPE(value); tb = PyException_GetTraceback(value); if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && _PyObject_HasAttrId(value, &PyId_print_file_and_line)) { PyObject *message, *filename, *text; int lineno, offset; if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); else { PyObject *line; Py_DECREF(value); value = message; line = PyUnicode_FromFormat(" File \"%U\", line %d\n", filename, lineno); Py_DECREF(filename); if (line != NULL) { PyFile_WriteObject(line, f, Py_PRINT_RAW); Py_DECREF(line); } if (text != NULL) { print_error_text(f, offset, text); Py_DECREF(text); } /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) err = -1; } } if (err) { /* Don't do anything else */ } else { PyObject* moduleName; const char *className; _Py_IDENTIFIER(__module__); assert(PyExceptionClass_Check(type)); className = PyExceptionClass_Name(type); if (className != NULL) { const char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = _PyObject_GetAttrId(type, &PyId___module__); if (moduleName == NULL || !PyUnicode_Check(moduleName)) { Py_XDECREF(moduleName); err = PyFile_WriteString("<unknown>", f); } else { if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW); err += PyFile_WriteString(".", f); } Py_DECREF(moduleName); } if (err == 0) { if (className == NULL) err = PyFile_WriteString("<unknown>", f); else err = PyFile_WriteString(className, f); } } if (err == 0 && (value != Py_None)) { PyObject *s = PyObject_Str(value); /* only print colon if the str() of the object is not the empty string */ if (s == NULL) { PyErr_Clear(); err = -1; PyFile_WriteString(": <exception str() failed>", f); } else if (!PyUnicode_Check(s) || PyUnicode_GetLength(s) != 0) err = PyFile_WriteString(": ", f); if (err == 0) err = PyFile_WriteObject(s, f, Py_PRINT_RAW); Py_XDECREF(s); } /* try to write a newline in any case */ if (err < 0) { PyErr_Clear(); } err += PyFile_WriteString("\n", f); Py_XDECREF(tb); Py_DECREF(value); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) PyErr_Clear(); }
void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) { int err = 0; PyObject *f = PySys_GetObject("stderr"); Py_INCREF(value); if (f == NULL) fprintf(stderr, "lost sys.stderr\n"); else { if (Py_FlushLine()) PyErr_Clear(); fflush(stdout); if (tb && tb != Py_None) err = PyTraceBack_Print(tb, f); if (err == 0 && PyObject_HasAttrString(value, "print_file_and_line")) { PyObject *message; const char *filename, *text; int lineno, offset; if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text)) PyErr_Clear(); else { char buf[10]; PyFile_WriteString(" File \"", f); if (filename == NULL) PyFile_WriteString("<string>", f); else PyFile_WriteString(filename, f); PyFile_WriteString("\", line ", f); PyOS_snprintf(buf, sizeof(buf), "%d", lineno); PyFile_WriteString(buf, f); PyFile_WriteString("\n", f); if (text != NULL) print_error_text(f, offset, text); Py_DECREF(value); value = message; /* Can't be bothered to check all those PyFile_WriteString() calls */ if (PyErr_Occurred()) err = -1; } } if (err) { /* Don't do anything else */ } else if (PyExceptionClass_Check(exception)) { PyObject* moduleName; char* className = PyExceptionClass_Name(exception); if (className != NULL) { char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } moduleName = PyObject_GetAttrString(exception, "__module__"); if (moduleName == NULL) err = PyFile_WriteString("<unknown>", f); else { char* modstr = PyString_AsString(moduleName); if (modstr && strcmp(modstr, "exceptions")) { err = PyFile_WriteString(modstr, f); err += PyFile_WriteString(".", f); } Py_DECREF(moduleName); } if (err == 0) { if (className == NULL) err = PyFile_WriteString("<unknown>", f); else err = PyFile_WriteString(className, f); } } else err = PyFile_WriteObject(exception, f, Py_PRINT_RAW); if (err == 0 && (value != Py_None)) { PyObject *s = PyObject_Str(value); /* only print colon if the str() of the object is not the empty string */ if (s == NULL) err = -1; else if (!PyString_Check(s) || PyString_GET_SIZE(s) != 0) err = PyFile_WriteString(": ", f); if (err == 0) err = PyFile_WriteObject(s, f, Py_PRINT_RAW); Py_XDECREF(s); } if (err == 0) err = PyFile_WriteString("\n", f); } Py_DECREF(value); /* If an error happened here, don't show it. XXX This is wrong, but too many callers rely on this behavior. */ if (err != 0) PyErr_Clear(); }
void PP_Fetch_Error_Text() { // called without exception happened! //assert(PyErr_Occurred()); char *tempstr; PyObject *errobj, *errdata, *errtraceback, *pystring; /* get latest python exception information */ /* this also clears the current exception */ PyErr_Fetch(&errobj, &errdata, &errtraceback); /* all 3 incref'd */ /* convert type and data to strings */ /* calls str() on both to stringify */ pystring = NULL; if (errobj != NULL && (pystring = PyObject_Str(errobj)) != NULL && /* str(errobj) */ (PyString_Check(pystring)) ) /* str() increfs */ { strncpy(PP_last_error_type, PyString_AsString(pystring), MAX); /*Py->C*/ PP_last_error_type[MAX-1] = '\0'; } else strcpy(PP_last_error_type, "<unknown exception type>"); Py_XDECREF(pystring); pystring = NULL; if (errdata != NULL && (pystring = PyObject_Str(errdata)) != NULL && /* str(): increfs */ (PyString_Check(pystring)) ) { strncpy(PP_last_error_info, PyString_AsString(pystring), MAX); /*Py->C*/ PP_last_error_info[MAX-1] = '\0'; } else strcpy(PP_last_error_info, "<unknown exception data>"); Py_XDECREF(pystring); /* convert traceback to string */ /* print text to a StringIO.StringIO() internal file object, then */ /* fetch by calling object's .getvalue() method (see lib manual); */ pystring = NULL; if (errtraceback != NULL && (PP_Run_Function("StringIO", "StringIO", "O", &pystring, "()") == 0) && (PyTraceBack_Print(errtraceback, pystring) == 0) && (PP_Run_Method(pystring, "getvalue", "s", &tempstr, "()") == 0) ) { strncpy(PP_last_error_trace, tempstr, MAX); PP_last_error_trace[MAX-1] = '\0'; free(tempstr); /* it's a strdup */ } else strcpy(PP_last_error_trace, "<unknown exception traceback>"); Py_XDECREF(pystring); Py_XDECREF(errobj); Py_XDECREF(errdata); /* this function owns all 3 objects */ Py_XDECREF(PP_last_traceback); /* they've been NULL'd out in Python */ PP_last_traceback = errtraceback; /* save/export raw traceback object */ }
PyObject* SlopNA_New(PyObject* exc_type, PyObject* exc_value, PyObject* exc_traceback) { assert(pg_activated); // TODO: use a free list like intobject and friends SlopNAObject* self = (SlopNAObject*)PyObject_MALLOC(sizeof(SlopNAObject)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); PyObject_INIT(self, &SlopNA_Type); // we can directly take these 2 fields, since they're picklable self->exc_type = exc_type; // could be NULL, in which case use Py_None if (exc_value) { self->exc_value = exc_value; } else { self->exc_value = Py_None; } Py_INCREF(self->exc_type); Py_INCREF(self->exc_value); // unfortunately exc_traceback isn't picklable, so we'll need to // call PyTraceBack_Print to print the traceback into a // cStringIO buffer, then convert that to a string if (!PycStringIO) { PycString_IMPORT; // don't repeat imports } PyObject* buf = PycStringIO->NewOutput(128); PyTraceBack_Print(exc_traceback, buf); self->exc_traceback_str = PycStringIO->cgetvalue(buf); Py_DECREF(buf); self->next_NA = NULL; // log this creation event in both verbose and binary logs: // for verbose log: PyObject* repr = NA_detailed_repr(self); PG_LOG(PyString_AsString(repr)); Py_DECREF(repr); // for binary log, each line is: // base64.b64encode(cPickle.dumps(context, -1)) // // where context is a dict with the following fields: // exc_type, exc_value, locals PyObject* context = PyDict_New(); PyObject* type_repr = PyObject_Repr(self->exc_type); PyObject* value_repr = PyObject_Repr(self->exc_value); PyDict_SetItemString(context, "exc_type", type_repr); PyDict_SetItemString(context, "exc_value", value_repr); PyDict_SetItemString(context, "locals", PyEval_GetLocals()); // pass in -1 to force cPickle to use a binary protocol PyObject* negative_one = PyInt_FromLong(-1); PyObject* pickled_context = PyObject_CallFunctionObjArgs(cPickle_dumpstr_func, context, negative_one, NULL); if (!pickled_context) { assert(PyErr_Occurred()); PyErr_Clear(); // hmmm, let's try removing locals and seeing if it's now picklable PyDict_DelItemString(context, "locals"); pickled_context = PyObject_CallFunctionObjArgs(cPickle_dumpstr_func, context, negative_one, NULL); } if (!pickled_context) { assert(PyErr_Occurred()); PyErr_Clear(); fprintf(stderr, "ERROR: pickled_context is unpicklable\n"); Py_Exit(1); } PyObject* encoded_line = PyObject_CallFunctionObjArgs(b64encode_func, pickled_context, NULL); fprintf(binary_log_file, "%s\n", PyString_AsString(encoded_line)); Py_DECREF(encoded_line); Py_DECREF(negative_one); Py_DECREF(context); Py_DECREF(value_repr); Py_DECREF(type_repr); return (PyObject*)self; }