static void faulthandler_fatal_error( int signum #ifdef HAVE_SIGACTION , siginfo_t *siginfo, void *ucontext #endif ) { const int fd = fatal_error.fd; unsigned int i; fault_handler_t *handler = NULL; PyThreadState *tstate; if (!fatal_error.enabled) return; for (i=0; i < faulthandler_nsignals; i++) { handler = &faulthandler_handlers[i]; if (handler->signum == signum) break; } if (handler == NULL) { /* faulthandler_nsignals == 0 (unlikely) */ return; } /* restore the previous handler */ #ifdef HAVE_SIGACTION (void)sigaction(handler->signum, &handler->previous, NULL); #else (void)signal(handler->signum, handler->previous); #endif handler->enabled = 0; PUTS(fd, "Fatal Python error: "); PUTS(fd, handler->name); PUTS(fd, "\n\n"); /* SIGSEGV, SIGFPE, SIGABRT, SIGBUS and SIGILL are synchronous signals and so are delivered to the thread that caused the fault. Get the Python thread state of the current thread. PyThreadState_Get() doesn't give the state of the thread that caused the fault if the thread released the GIL, and so this function cannot be used. Read the thread local storage (TLS) instead: call PyGILState_GetThisThreadState(). */ tstate = PyGILState_GetThisThreadState(); if (tstate == NULL) return; if (fatal_error.all_threads) _Py_DumpTracebackThreads(fd, tstate->interp, tstate); else _Py_DumpTraceback(fd, tstate); #ifdef MS_WINDOWS if (signum == SIGSEGV) { /* don't call explictly the previous handler for SIGSEGV in this signal handler, because the Windows signal handler would not be called */ return; } #endif /* call the previous signal handler: it is called immediatly if we use sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */ raise(signum); }
void PythonContext::executeString(const QString &filename, const QString &source) { if(!initialised()) { emit exception( lit("SystemError"), tr("Python integration failed to initialise, see diagnostic log for more information."), -1, {}); return; } location.file = filename; location.line = 1; PyGILState_STATE gil = PyGILState_Ensure(); PyObject *compiled = Py_CompileString(source.toUtf8().data(), filename.toUtf8().data(), source.count(QLatin1Char('\n')) == 0 ? Py_single_input : Py_file_input); PyObject *ret = NULL; if(compiled) { PyObject *traceContext = PyDict_New(); uintptr_t thisint = (uintptr_t) this; uint64_t thisuint64 = (uint64_t)thisint; PyObject *thisobj = PyLong_FromUnsignedLongLong(thisuint64); PyDict_SetItemString(traceContext, "thisobj", thisobj); PyDict_SetItemString(traceContext, "compiled", compiled); PyEval_SetTrace(&PythonContext::traceEvent, traceContext); m_Abort = false; m_State = PyGILState_GetThisThreadState(); ret = PyEval_EvalCode(compiled, context_namespace, context_namespace); m_State = NULL; // catch any output outputTick(); PyEval_SetTrace(NULL, NULL); Py_XDECREF(thisobj); Py_XDECREF(traceContext); } Py_DecRef(compiled); QString typeStr; QString valueStr; int finalLine = -1; QList<QString> frames; bool caughtException = (ret == NULL); if(caughtException) FetchException(typeStr, valueStr, finalLine, frames); Py_XDECREF(ret); PyGILState_Release(gil); if(caughtException) emit exception(typeStr, valueStr, finalLine, frames); }