static int tb_printinternal(tracebackobject *tb, PyObject *f, int limit) { int err = 0; int depth = 0; tracebackobject *tb1 = tb; while (tb1 != NULL) { depth++; tb1 = tb1->tb_next; } while (tb != NULL && err == 0) { if (depth <= limit) { if (Py_OptimizeFlag) tb->tb_lineno = PyCode_Addr2Line( tb->tb_frame->f_code, tb->tb_lasti); err = tb_displayline(f, PyString_AsString( tb->tb_frame->f_code->co_filename), tb->tb_lineno, PyString_AsString(tb->tb_frame->f_code->co_name)); } depth--; tb = tb->tb_next; if (err == 0) err = PyErr_CheckSignals(); } return err; }
static void dump_frame(int fd, PyFrameObject *frame) { PyCodeObject *code; int lineno; code = frame->f_code; PUTS(fd, " File "); if (code != NULL && code->co_filename != NULL && PyUnicode_Check(code->co_filename)) { write(fd, "\"", 1); dump_ascii(fd, code->co_filename); write(fd, "\"", 1); } else { PUTS(fd, "???"); } /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */ lineno = PyCode_Addr2Line(code, frame->f_lasti); PUTS(fd, ", line "); dump_decimal(fd, lineno); PUTS(fd, " in "); if (code != NULL && code->co_name != NULL && PyUnicode_Check(code->co_name)) dump_ascii(fd, code->co_name); else PUTS(fd, "???"); write(fd, "\n", 1); }
static PyObject * pygst_debug_log (PyObject * pyobject, PyObject * string, GstDebugLevel level, gboolean isgstobject) { #ifndef GST_DISABLE_GST_DEBUG gchar *str; gchar *function; gchar *filename; int lineno; PyFrameObject *frame; GObject *object = NULL; if (!PyArg_ParseTuple (string, "s:gst.debug_log", &str)) { PyErr_SetString (PyExc_TypeError, "Need a string!"); return NULL; } frame = PyEval_GetFrame (); function = PyString_AsString (frame->f_code->co_name); filename = g_path_get_basename (PyString_AsString (frame->f_code->co_filename)); lineno = PyCode_Addr2Line (frame->f_code, frame->f_lasti); /* gst_debug_log : category, level, file, function, line, object, format, va_list */ if (isgstobject) object = G_OBJECT (pygobject_get (pyobject)); gst_debug_log (python_debug, level, filename, function, lineno, object, "%s", str); if (filename) g_free (filename); #endif Py_INCREF (Py_None); return Py_None; }
int PyFrame_GetLineNumber(PyFrameObject *f) { if (f->f_trace) return f->f_lineno; else return PyCode_Addr2Line(f->f_code, f->f_lasti); }
int PyFrame_GetLineNumber(PyFrameObject *frame) { if (frame->f_trace) { return frame->f_lineno; } else { return PyCode_Addr2Line(frame->f_code, frame->f_lasti); } }
static PyObject * frame_getlineno(PyFrameObject *f, void *closure) { int lineno; if (f->f_trace) lineno = f->f_lineno; else lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); return PyInt_FromLong(lineno); }
PyObject* tostring(PyObject* self, PyObject* gen) { if(PyGen_Check(gen)) { PyFrameObject* frame = ((PyGenObject*)gen)->gi_frame; if(!frame) return PyString_FromString("<no frame>"); int ilineno = PyCode_Addr2Line(frame->f_code, frame->f_lasti); PyObject* lineno = PyInt_FromLong(ilineno); // new ref PyObject* codeline = PyObject_CallFunctionObjArgs(py_getline, frame->f_code->co_filename, lineno, NULL); // new ref Py_CLEAR(lineno); if(!codeline) return NULL; PyObject* codeline_stripped = PyObject_CallMethod(codeline, "strip", NULL); // new ref Py_CLEAR(codeline); if(!codeline_stripped) return NULL; PyObject* result = PyString_FromFormat(" File \"%s\", line %d, in %s\n %s", PyString_AsString(frame->f_code->co_filename), ilineno, PyString_AsString(frame->f_code->co_name), PyString_AsString(codeline_stripped)); // new ref Py_CLEAR(codeline_stripped); return result; } else if(gen->ob_type == &PyCompose_Type) { PyComposeObject* cmps = (PyComposeObject*) gen; PyObject* result = NULL; PyObject** generator = cmps->generators_base; while(generator < cmps->generators_top) { PyObject* s = tostring(NULL, *generator++); if(!result) result = s; else { PyString_ConcatAndDel(&result, PyString_FromString("\n")); PyString_ConcatAndDel(&result, s); } } return result; } PyErr_SetString(PyExc_TypeError, "tostring() expects generator"); return NULL; }
static int frame_settrace(PyFrameObject *f, PyObject* v, void *closure) { /* We rely on f_lineno being accurate when f_trace is set. */ PyObject* old_value = f->f_trace; Py_XINCREF(v); f->f_trace = v; if (v != NULL) f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); Py_XDECREF(old_value); return 0; }
void log_NA_event(const char* event_name) { PyFrameObject* f = PyEval_GetFrame(); // stolen from frame_getlineno in Objects/frameobject.c int lineno; if (f->f_trace) lineno = f->f_lineno; else lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); PG_LOG_PRINTF("{%s | %s %s:%d}\n", event_name, PyString_AsString(f->f_code->co_filename), PyString_AsString(f->f_code->co_name), lineno); }
// Python interpreter retrieval routine adapted from // https://stackoverflow.com/a/8706144 std::string getPythonInterpreterStackTrace() { std::stringstream stack_trace; AutoGIL gil; PyThreadState *tstate = PyThreadState_GET(); if (NULL != tstate && NULL != tstate->frame) { PyFrameObject *frame = tstate->frame; while (NULL != frame) { int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti); std::string filename = THPUtils_unpackString(frame->f_code->co_filename); std::string funcname = THPUtils_unpackString(frame->f_code->co_name); stack_trace << filename << "(" << line << "): " << funcname << "\n"; frame = frame->f_back; } } return stack_trace.str(); }
static void dump_frame(int fd, PyFrameObject *frame) { PyCodeObject *code; int lineno; code = frame->f_code; PUTS(fd, " File "); if (code != NULL && code->co_filename != NULL && PyUnicode_Check(code->co_filename)) { PUTS(fd, "\""); _Py_DumpASCII(fd, code->co_filename); PUTS(fd, "\""); } else { PUTS(fd, "???"); } /* PyFrame_GetLineNumber() was introduced in Python 2.7.0 and 3.2.0 */ lineno = PyCode_Addr2Line(code, frame->f_lasti); PUTS(fd, ", line "); if (lineno >= 0) { _Py_DumpDecimal(fd, (unsigned long)lineno); } else { PUTS(fd, "???"); } PUTS(fd, " in "); if (code != NULL && code->co_name != NULL && PyUnicode_Check(code->co_name)) { _Py_DumpASCII(fd, code->co_name); } else { PUTS(fd, "???"); } PUTS(fd, "\n"); }
static PyTracebackObject * newtracebackobject(PyTracebackObject *next, PyFrameObject *frame) { PyTracebackObject *tb; if ((next != NULL && !PyTraceBack_Check(next)) || frame == NULL || !PyFrame_Check(frame)) { PyErr_BadInternalCall(); return NULL; } tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); if (tb != NULL) { Py_XINCREF(next); tb->tb_next = next; Py_XINCREF(frame); tb->tb_frame = frame; tb->tb_lasti = frame->f_lasti; tb->tb_lineno = PyCode_Addr2Line(frame->f_code, frame->f_lasti); PyObject_GC_Track(tb); } return tb; }
ScriptResult PythonEngine::parseError() { // error ScriptResult error; error.isError = true; PyObject *error_type = NULL; PyObject *error_value = NULL; PyObject *error_traceback = NULL; PyObject *error_string = NULL; PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_NormalizeException(&error_type, &error_value, &error_traceback); if (error_traceback) { PyTracebackObject *traceback = (PyTracebackObject *) error_traceback; error.line = traceback->tb_lineno; error.text.append(QString("Line %1: ").arg(traceback->tb_lineno)); while (traceback) { PyFrameObject *frame = traceback->tb_frame; if (frame && frame->f_code) { PyCodeObject* codeObject = frame->f_code; if (PyString_Check(codeObject->co_filename)) error.traceback.append(QString("File '%1'").arg(PyString_AsString(codeObject->co_filename))); int errorLine = PyCode_Addr2Line(codeObject, frame->f_lasti); error.traceback.append(QString(", line %1").arg(errorLine)); if (PyString_Check(codeObject->co_name)) error.traceback.append(QString(", in %1").arg(PyString_AsString(codeObject->co_name))); } error.traceback.append(QString("\n")); traceback = traceback->tb_next; } } error.traceback = error.traceback.trimmed(); if (error_type != NULL && (error_string = PyObject_Str(error_type)) != NULL && (PyString_Check(error_string))) { Py_INCREF(error_string); error.text.append(PyString_AsString(error_string)); Py_XDECREF(error_string); } else { error.text.append("\n<unknown exception type>"); } if (error_value != NULL && (error_string = PyObject_Str(error_value)) != NULL && (PyString_Check(error_string))) { Py_INCREF(error_string); error.text.append("\n"); error.text.append(PyString_AsString(error_string)); Py_XDECREF(error_string); } else { error.text.append("\n<unknown exception data>"); } Py_XDECREF(error_type); Py_XDECREF(error_value); Py_XDECREF(error_traceback); PyErr_Clear(); return error; }
bool PythonScript::checkRuntimeError() { if (!PyErr_Occurred()) return true; std::string pyException = ""; PyObject* pyError_type = nullptr; PyObject* pyError_value = nullptr; PyObject* pyError_traceback = nullptr; PyObject* pyError_string = nullptr; PyErr_Fetch(&pyError_type, &pyError_value, &pyError_traceback); int errorLine = -1; std::string stacktraceStr; if (pyError_traceback) { PyTracebackObject* traceback = (PyTracebackObject*)pyError_traceback; while (traceback) { PyFrameObject* frame = traceback->tb_frame; std::string stacktraceLine; if (frame && frame->f_code) { PyCodeObject* codeObject = frame->f_code; if (PyValueParser::is<std::string>(codeObject->co_filename)) stacktraceLine.append(std::string(" File \"") + PyValueParser::parse<std::string>(codeObject->co_filename) + std::string("\", ")); errorLine = PyCode_Addr2Line(codeObject, frame->f_lasti); stacktraceLine.append(std::string("line ") + toString(errorLine)); if (PyValueParser::is<std::string>(codeObject->co_name)) stacktraceLine.append(std::string(", in ") + PyValueParser::parse<std::string>(codeObject->co_name)); } stacktraceLine.append("\n"); stacktraceStr = stacktraceLine + stacktraceStr; traceback = traceback->tb_next; } } std::stringstream s; s << errorLine; pyException.append(std::string("[") + s.str() + std::string("] ")); if (pyError_value && (pyError_string = PyObject_Str(pyError_value)) != nullptr && (PyValueParser::is<std::string>(pyError_string))) { pyException.append(PyValueParser::parse<std::string>(pyError_string)); Py_XDECREF(pyError_string); pyError_string = nullptr; } else { pyException.append("<No data available>"); } pyException.append("\n"); // finally append stacktrace string if (!stacktraceStr.empty()) { pyException.append("Stacktrace (most recent call first):\n"); pyException.append(stacktraceStr); } else { pyException.append("<No stacktrace available>"); LogWarn("Failed to parse traceback"); } Py_XDECREF(pyError_type); Py_XDECREF(pyError_value); Py_XDECREF(pyError_traceback); LogError(pyException); PyInviwo::getPtr()->pythonExecutionOutputEvent(pyException, sysstderr); return false; }
/* Returns 0 on error (no new refs), 1 on success */ static int setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, PyObject **module, PyObject **registry) { PyObject *globals; /* Setup globals and lineno. */ PyFrameObject *f = PyThreadState_GET()->frame; while (--stack_level > 0 && f != NULL) f = f->f_back; if (f == NULL) { globals = PyThreadState_Get()->interp->sysdict; *lineno = 1; } else { globals = f->f_globals; *lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); } *module = NULL; /* Setup registry. */ assert(globals != NULL); assert(PyDict_Check(globals)); *registry = PyDict_GetItemString(globals, "__warningregistry__"); if (*registry == NULL) { int rc; *registry = PyDict_New(); if (*registry == NULL) return 0; rc = PyDict_SetItemString(globals, "__warningregistry__", *registry); if (rc < 0) goto handle_error; } else Py_INCREF(*registry); /* Setup module. */ *module = PyDict_GetItemString(globals, "__name__"); if (*module == NULL) { *module = PyString_FromString("<string>"); if (*module == NULL) goto handle_error; } else Py_INCREF(*module); /* Setup filename. */ *filename = PyDict_GetItemString(globals, "__file__"); if (*filename != NULL) { Py_ssize_t len = PyString_Size(*filename); const char *file_str = PyString_AsString(*filename); if (file_str == NULL || (len < 0 && PyErr_Occurred())) goto handle_error; /* if filename.lower().endswith((".pyc", ".pyo")): */ if (len >= 4 && file_str[len-4] == '.' && tolower(file_str[len-3]) == 'p' && tolower(file_str[len-2]) == 'y' && (tolower(file_str[len-1]) == 'c' || tolower(file_str[len-1]) == 'o')) { *filename = PyString_FromStringAndSize(file_str, len-1); if (*filename == NULL) goto handle_error; } else Py_INCREF(*filename); } else { const char *module_str = PyString_AsString(*module); if (module_str && strcmp(module_str, "__main__") == 0) { PyObject *argv = PySys_GetObject("argv"); if (argv != NULL && PyList_Size(argv) > 0) { int is_true; *filename = PyList_GetItem(argv, 0); Py_INCREF(*filename); /* If sys.argv[0] is false, then use '__main__'. */ is_true = PyObject_IsTrue(*filename); if (is_true < 0) { Py_DECREF(*filename); goto handle_error; } else if (!is_true) { Py_DECREF(*filename); *filename = PyString_FromString("__main__"); if (*filename == NULL) goto handle_error; } } else { /* embedded interpreters don't have sys.argv, see bug #839151 */ *filename = PyString_FromString("__main__"); if (*filename == NULL) goto handle_error; } } if (*filename == NULL) { *filename = *module; Py_INCREF(*filename); } } return 1; handle_error: /* filename not XDECREF'ed here as there is no way to jump here with a dangling reference. */ Py_XDECREF(*registry); Py_XDECREF(*module); return 0; }
ErrorResult PythonEngine::parseError() { QString traceback; QString text; int line = -1; PyErr_NormalizeException(&errorType, &errorValue, &errorTraceback); if (errorTraceback) { PyTracebackObject *tb = (PyTracebackObject *) errorTraceback; line = tb->tb_lineno; text.append(QString("Line %1: ").arg(tb->tb_lineno)); while (tb) { PyFrameObject *frame = tb->tb_frame; if (frame && frame->f_code) { PyCodeObject* codeObject = frame->f_code; if (PyString_Check(codeObject->co_filename)) traceback.append(QString("File '%1'").arg(PyString_AsString(codeObject->co_filename))); int errorLine = PyCode_Addr2Line(codeObject, frame->f_lasti); traceback.append(QString(", line %1").arg(errorLine)); if (PyString_Check(codeObject->co_name)) traceback.append(QString(", in %1").arg(PyString_AsString(codeObject->co_name))); } traceback.append(QString("\n")); tb = tb->tb_next; } } traceback = traceback.trimmed(); PyObject *errorString = NULL; if (errorType != NULL && (errorString = PyObject_Str(errorType)) != NULL && (PyString_Check(errorString))) { Py_INCREF(errorString); text.append(PyString_AsString(errorString)); Py_XDECREF(errorString); } else { text.append("\n<unknown exception type>"); } if (errorValue != NULL && (errorString = PyObject_Str(errorValue)) != NULL && (PyString_Check(errorString))) { Py_INCREF(errorString); text.append("\n"); text.append(PyString_AsString(errorString)); Py_XDECREF(errorString); } else { text.append("\n<unknown exception data>"); } Py_XDECREF(errorType); errorType = NULL; Py_XDECREF(errorValue); errorValue = NULL; Py_XDECREF(errorTraceback); errorTraceback = NULL; PyErr_Clear(); return ErrorResult(text, traceback, line); }
//============================================================================= // METHOD : SPELLbytecode::analyze //============================================================================= void SPELLbytecode::analyze() { assert( m_code != NULL ); // Pointer to initial instruction (used by macros) unsigned char* first_instr = (unsigned char*) PyString_AS_STRING(m_code->co_code); // Pointer to current instruction (used by macros) register unsigned char* next_instr = first_instr; // Opcode argument unsigned int oparg; // Stores the previous line unsigned int prevLine = 0; // Stores the last opcode unsigned int prevOpCode = 0; // Opcode count in line unsigned short opcodeCount = 0; // Will be true when there is no more bytecode to process bool finished = false; unsigned int callDepth = 0; // Try block structure TryBlock tb; tb.try_lineno = 0; tb.end_try_lineno = 0; tb.except_lineno = 0; tb.end_except_lineno = 0; tb.end_lineno = 0; // Holds the bytecode offset for except and finally statements unsigned int except_offset = 0; unsigned int finally_offset = 0; while(not finished) { // Create one BLine info structure per bytecode instruction BLine info; // Get the instruction offset info.offset = INSTR_OFFSET(); // Get the corresponding script line info.lineno = PyCode_Addr2Line(m_code, info.offset); // Obtain the opcode info.opcode = NEXTOP(); // Track the number of opcodes per line in the lnotab. if ((prevLine>0) && (info.lineno != prevLine)) { opcodeCount = 0; } else { opcodeCount++; } ////////////////////////////////////////////////////////////////////////////////// // PHASE 1 - UPDATE PREVIOUS LINE INFORMATION (ALREADY STORED) IF NEEDED ////////////////////////////////////////////////////////////////////////////////// // #1 Detect binary add. This helps us detect lines that shall be executed together // like when statements spread over several lines with binary add (+\) if ((opcodeCount == 0)&&(prevOpCode == BINARY_ADD)&&(info.opcode==LOAD_CONST)) { LineList::iterator it = m_lines.end(); it--; BLine prev = *it; m_lines.pop_back(); prev.keepWithNext = true; m_lines.push_back(prev); } ////////////////////////////////////////////////////////////////////////////////// // #2 Special checks for return statements: we may need to update the previous line if (info.opcode == RETURN_VALUE && ((prevOpCode == LOAD_FAST || prevOpCode == LOAD_CONST))) { LineList::iterator it = m_lines.end(); it--; BLine prev = *it; m_lines.pop_back(); prev.returnConst = true; m_lines.push_back(prev); } // We will ignore this, for the moment oparg = 0; // To decide wether store the bline information or not bool storeit = false; if (HAS_ARG(info.opcode)) oparg = NEXTARG(); ////////////////////////////////////////////////////////////////////////////////// // PHASE 2 - BUILD AND STORE NEXT BLINE INFORMATION ////////////////////////////////////////////////////////////////////////////////// if (( prevLine > 0 ) && ( info.lineno != prevLine )) { // Default values info.executable = false; info.returnConst = false; info.keepWithNext = false; /** \todo // Depending on the bytecode, either set the block as active, // or finish the loop (RETURN_VALUE is found at the end of the script) // This is maybe wrong, need to check if RETURN_VALUE is found // in function code objects, probably yes... */ switch(info.opcode) { case LOAD_NAME: case LOAD_GLOBAL: case LOAD_CONST: callDepth++; info.executable = true; break; case CALL_FUNCTION: callDepth--; info.executable = true; break; case STORE_NAME: case IMPORT_NAME: case JUMP_FORWARD: case JUMP_IF_FALSE: case JUMP_IF_TRUE: case JUMP_ABSOLUTE: case RETURN_VALUE: { info.executable = (callDepth==0); break; } default: info.executable = true; break; } // Store the info m_lines.push_back(info); } // The very first line is always executable, and needs to be stored explicitly else if (prevLine == 0) { info.executable = true; // Store the info m_lines.push_back(info); } ////////////////////////////////////////////////////////////////////////////////// // PHASE 3 - ADDITIONAL INFORMATION FOR TRY BLOCKS, LAST ADDRESS, LAST LINE ////////////////////////////////////////////////////////////////////////////////// switch(info.opcode) { case RETURN_VALUE: m_lastAddr = info.offset; finished = true; break; case SETUP_EXCEPT: tb.try_lineno = info.lineno; except_offset = info.offset + oparg + 3; // This is the real destination offset break; case SETUP_FINALLY: finally_offset = info.offset + oparg + 3; // This is the 'finally' destination offset break; case END_FINALLY: if (tb.try_lineno != 0 && tb.end_lineno == 0) { tb.end_lineno = info.lineno; tb.end_except_lineno = info.lineno; m_tryBlocks.push_back( tb ); tb.try_lineno = 0; tb.end_try_lineno = 0; tb.except_lineno = 0; tb.end_except_lineno = 0; tb.end_lineno = 0; } else { // Update the last try block to update it with the finally block TryBlockList::iterator it = m_tryBlocks.end(); it--; TryBlock prev = *it; m_tryBlocks.pop_back(); prev.end_except_lineno = prev.end_lineno; prev.end_lineno = info.lineno; m_tryBlocks.push_back( prev ); } break; } // This should always happen between a SETUP_EXCEPT and an END_FINALLY if ( (tb.try_lineno >0) && (except_offset == info.offset)) { // The last line before the except tb.end_try_lineno = prevLine; // The line of the except tb.except_lineno = info.lineno; } prevLine = info.lineno; prevOpCode = info.opcode; m_lastLine = info.lineno; } }