QString QgsPythonUtilsImpl::getTraceback()
{
#define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;}

  // acquire global interpreter lock to ensure we are in a consistent state
  PyGILState_STATE gstate;
  gstate = PyGILState_Ensure();

  QString errMsg;
  QString result;

  PyObject *modStringIO = NULL;
  PyObject *modTB = NULL;
  PyObject *obStringIO = NULL;
  PyObject *obResult = NULL;

  PyObject *type, *value, *traceback;

  PyErr_Fetch( &type, &value, &traceback );
  PyErr_NormalizeException( &type, &value, &traceback );

  modStringIO = PyImport_ImportModule( "cStringIO" );
  if ( modStringIO == NULL )
    TRACEBACK_FETCH_ERROR( "can't import cStringIO" );

  obStringIO = PyObject_CallMethod( modStringIO, ( char* ) "StringIO", NULL );

  /* Construct a cStringIO object */
  if ( obStringIO == NULL )
    TRACEBACK_FETCH_ERROR( "cStringIO.StringIO() failed" );

  modTB = PyImport_ImportModule( "traceback" );
  if ( modTB == NULL )
    TRACEBACK_FETCH_ERROR( "can't import traceback" );

  obResult = PyObject_CallMethod( modTB, ( char* ) "print_exception",
                                  ( char* ) "OOOOO",
                                  type, value ? value : Py_None,
                                  traceback ? traceback : Py_None,
                                  Py_None,
                                  obStringIO );

  if ( obResult == NULL )
    TRACEBACK_FETCH_ERROR( "traceback.print_exception() failed" );
  Py_DECREF( obResult );

  obResult = PyObject_CallMethod( obStringIO, ( char* ) "getvalue", NULL );
  if ( obResult == NULL )
    TRACEBACK_FETCH_ERROR( "getvalue() failed." );

  /* And it should be a string all ready to go - duplicate it. */
  if ( !PyString_Check( obResult ) )
    TRACEBACK_FETCH_ERROR( "getvalue() did not return a string" );

  result = PyString_AsString( obResult );

done:

  // All finished - first see if we encountered an error
  if ( result.isEmpty() && !errMsg.isEmpty() )
  {
    result = errMsg;
  }

  Py_XDECREF( modStringIO );
  Py_XDECREF( modTB );
  Py_XDECREF( obStringIO );
  Py_XDECREF( obResult );
  Py_XDECREF( value );
  Py_XDECREF( traceback );
  Py_XDECREF( type );

  // we are done calling python API, release global interpreter lock
  PyGILState_Release( gstate );

  return result;
}
/* This function is called by the tp_dealloc handler to clear weak references.
 *
 * This iterates through the weak references for 'object' and calls callbacks
 * for those references which have one.  It returns when all callbacks have
 * been attempted.
 */
void
PyObject_ClearWeakRefs(PyObject *object)
{
    PyWeakReference **list;

    if (object == NULL
        || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))
        || object->ob_refcnt != 0) {
        PyErr_BadInternalCall();
        return;
    }
    list = GET_WEAKREFS_LISTPTR(object);
    /* Remove the callback-less basic and proxy references */
    if (*list != NULL && (*list)->wr_callback == NULL) {
        clear_weakref(*list);
        if (*list != NULL && (*list)->wr_callback == NULL)
            clear_weakref(*list);
    }
    if (*list != NULL) {
        PyWeakReference *current = *list;
        Py_ssize_t count = _PyWeakref_GetWeakrefCount(current);
        PyObject *err_type, *err_value, *err_tb;

        PyErr_Fetch(&err_type, &err_value, &err_tb);
        if (count == 1) {
            PyObject *callback = current->wr_callback;

            current->wr_callback = NULL;
            clear_weakref(current);
            if (callback != NULL) {
                if (current->ob_refcnt > 0)
                    handle_callback(current, callback);
                Py_DECREF(callback);
            }
        }
        else {
            PyObject *tuple;
            Py_ssize_t i = 0;

            tuple = PyTuple_New(count * 2);
            if (tuple == NULL) {
                _PyErr_ReplaceException(err_type, err_value, err_tb);
                return;
            }

            for (i = 0; i < count; ++i) {
                PyWeakReference *next = current->wr_next;

                if (current->ob_refcnt > 0)
                {
                    Py_INCREF(current);
                    PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
                    PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
                }
                else {
                    Py_DECREF(current->wr_callback);
                }
                current->wr_callback = NULL;
                clear_weakref(current);
                current = next;
            }
            for (i = 0; i < count; ++i) {
                PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);

                /* The tuple may have slots left to NULL */
                if (callback != NULL) {
                    PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
                    handle_callback((PyWeakReference *)item, callback);
                }
            }
            Py_DECREF(tuple);
        }
        assert(!PyErr_Occurred());
        PyErr_Restore(err_type, err_value, err_tb);
    }
}
示例#3
0
static int GREENLET_NOINLINE(g_initialstub)(void* mark)
{
	int err;
	PyObject *o, *run;
	PyObject *exc, *val, *tb;
	PyObject *run_info;
	PyGreenlet* self = ts_target;
	PyObject* args = ts_passaround_args;
	PyObject* kwargs = ts_passaround_kwargs;

	/* save exception in case getattr clears it */
	PyErr_Fetch(&exc, &val, &tb);
	/* self.run is the object to call in the new greenlet */
	run = PyObject_GetAttrString((PyObject*) self, "run");
	if (run == NULL) {
		Py_XDECREF(exc);
		Py_XDECREF(val);
		Py_XDECREF(tb);
		return -1;
	}
	/* restore saved exception */
	PyErr_Restore(exc, val, tb);

	/* recheck the state in case getattr caused thread switches */
	if (!STATE_OK) {
		Py_DECREF(run);
		return -1;
	}

	/* recheck run_info in case greenlet reparented anywhere above */
	run_info = green_statedict(self);
	if (run_info == NULL || run_info != ts_current->run_info) {
		Py_DECREF(run);
		PyErr_SetString(PyExc_GreenletError, run_info
		                ? "cannot switch to a different thread"
		                : "cannot switch to a garbage collected greenlet");
		return -1;
	}

	/* by the time we got here another start could happen elsewhere,
	 * that means it should now be a regular switch
	 */
	if (PyGreenlet_STARTED(self)) {
		Py_DECREF(run);
		ts_passaround_args = args;
		ts_passaround_kwargs = kwargs;
		return 1;
	}

	/* start the greenlet */
	self->stack_start = NULL;
	self->stack_stop = (char*) mark;
	if (ts_current->stack_start == NULL) {
		/* ts_current is dying */
		self->stack_prev = ts_current->stack_prev;
	}
	else {
		self->stack_prev = ts_current;
	}
	self->top_frame = NULL;
	self->exc_type = NULL;
	self->exc_value = NULL;
	self->exc_traceback = NULL;
	self->recursion_depth = PyThreadState_GET()->recursion_depth;

	/* restore arguments in case they are clobbered */
	ts_target = self;
	ts_passaround_args = args;
	ts_passaround_kwargs = kwargs;

	/* perform the initial switch */
	err = g_switchstack();

	/* returns twice!
	   The 1st time with err=1: we are in the new greenlet
	   The 2nd time with err=0: back in the caller's greenlet
	*/
	if (err == 1) {
		/* in the new greenlet */
		PyGreenlet* origin;
#if GREENLET_USE_TRACING
		PyObject* tracefunc;
#endif
		PyObject* result;
		PyGreenlet* parent;
		self->stack_start = (char*) 1;  /* running */

		/* grab origin while we still can */
		origin = ts_origin;
		ts_origin = NULL;

		/* now use run_info to store the statedict */
		o = self->run_info;
		self->run_info = green_statedict(self->parent);
		Py_INCREF(self->run_info);
		Py_XDECREF(o);

#if GREENLET_USE_TRACING
		if ((tracefunc = PyDict_GetItem(self->run_info, ts_tracekey)) != NULL) {
			Py_INCREF(tracefunc);
			if (g_calltrace(tracefunc, args ? ts_event_switch : ts_event_throw, origin, self) < 0) {
				/* Turn trace errors into switch throws */
				Py_CLEAR(kwargs);
				Py_CLEAR(args);
			}
			Py_DECREF(tracefunc);
		}
#endif
		Py_DECREF(origin);

		if (args == NULL) {
			/* pending exception */
			result = NULL;
		} else {
			/* call g.run(*args, **kwargs) */
			result = PyEval_CallObjectWithKeywords(
				run, args, kwargs);
			Py_DECREF(args);
			Py_XDECREF(kwargs);
		}
		Py_DECREF(run);
		result = g_handle_exit(result);

		/* jump back to parent */
		self->stack_start = NULL;  /* dead */
		for (parent = self->parent; parent != NULL; parent = parent->parent) {
			result = g_switch(parent, result, NULL);
			/* Return here means switch to parent failed,
			 * in which case we throw *current* exception
			 * to the next parent in chain.
			 */
			assert(result == NULL);
		}
		/* We ran out of parents, cannot continue */
		PyErr_WriteUnraisable((PyObject *) self);
		Py_FatalError("greenlets cannot continue");
	}
	/* back in the parent */
	if (err < 0) {
		/* start failed badly, restore greenlet state */
		self->stack_start = NULL;
		self->stack_stop = NULL;
		self->stack_prev = NULL;
	}
	return err;
}
/* Reads a buffer from the file object
 * Make sure to hold the GIL state before calling this function
 * Returns the number of bytes read if successful, or -1 on error
 */
ssize_t pyewf_file_object_read_buffer(
         PyObject *file_object,
         uint8_t *buffer,
         size_t size,
         libcerror_error_t **error )
{
	PyObject *argument_size       = NULL;
	PyObject *exception_string    = NULL;
	PyObject *exception_traceback = NULL;
	PyObject *exception_type      = NULL;
	PyObject *exception_value     = NULL;
	PyObject *method_name         = NULL;
	PyObject *method_result       = NULL;
	char *error_string            = NULL;
	char *safe_buffer             = NULL;
	static char *function         = "pyewf_file_object_read_buffer";
	Py_ssize_t safe_read_count    = 0;
	ssize_t read_count            = 0;
	int result                    = 0;

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( buffer == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid buffer.",
		 function );

		return( -1 );
	}
	if( size > (size_t) SSIZE_MAX )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( size > 0 )
	{
		method_name = PyString_FromString(
			       "read" );

		argument_size = PyLong_FromSize_t(
				 size );

		PyErr_Clear();

		method_result = PyObject_CallMethodObjArgs(
				 file_object,
				 method_name,
				 argument_size,
				 NULL );

		if( PyErr_Occurred() )
		{
			PyErr_Fetch(
			 &exception_type,
			 &exception_value,
			 &exception_traceback );

			exception_string = PyObject_Repr(
					    exception_value );

			error_string = PyString_AsString(
					exception_string );

			if( error_string != NULL )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read from file object with error: %s.",
				 function,
				 error_string );
			}
			else
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read from file object.",
				 function );
			}
			Py_DecRef(
			 exception_string );

			goto on_error;
		}
		result = PyString_AsStringAndSize(
			  method_result,
			  &safe_buffer,
			  &safe_read_count );

		if( result == -1 )
		{
			PyErr_Fetch(
			 &exception_type,
			 &exception_value,
			 &exception_traceback );

			exception_string = PyObject_Repr(
					    exception_value );

			error_string = PyString_AsString(
					exception_string );

			if( error_string != NULL )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read from file object with error: %s.",
				 function,
				 error_string );
			}
			else
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_READ_FAILED,
				 "%s: unable to read from file object.",
				 function );
			}
			Py_DecRef(
			 exception_string );

			goto on_error;
		}
		if( safe_read_count > (Py_ssize_t) SSIZE_MAX )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
			 "%s: invalid read count value exceeds maximum.",
			 function );

			goto on_error;
		}
		read_count = (ssize_t) safe_read_count;

		if( memory_copy(
		     buffer,
		     safe_buffer,
		     read_count ) == NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_MEMORY,
			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
			 "%s: unable to data to buffer.",
			 function );

			goto on_error;
		}
		Py_DecRef(
		 method_result );

		Py_DecRef(
		 argument_size );

		Py_DecRef(
		 method_name );
	}
	return( read_count );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( argument_size != NULL )
	{
		Py_DecRef(
		 argument_size );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
/* Seeks a certain offset within the file object
 * Make sure to hold the GIL state before calling this function
 * Returns 1 if successful or -1 on error
 */
int pyewf_file_object_seek_offset(
     PyObject *file_object,
     off64_t offset,
     int whence,
     libcerror_error_t **error )
{
	PyObject *argument_offset     = NULL;
	PyObject *argument_whence     = NULL;
	PyObject *exception_string    = NULL;
	PyObject *exception_traceback = NULL;
	PyObject *exception_type      = NULL;
	PyObject *exception_value     = NULL;
	PyObject *method_name         = NULL;
	PyObject *method_result       = NULL;
	char *error_string            = NULL;
	static char *function         = "pyewf_file_object_seek_offset";

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
#if defined( HAVE_LONG_LONG )
	if( offset > (off64_t) INT64_MAX )
#else
	if( offset > (off64_t) LONG_MAX )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid offset value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( ( whence != SEEK_CUR )
	 && ( whence != SEEK_END )
	 && ( whence != SEEK_SET ) )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
		 "%s: unsupported whence.",
		 function );

		return( -1 );
	}
	method_name = PyString_FromString(
	               "seek" );

#if defined( HAVE_LONG_LONG )
	argument_offset = PyLong_FromLongLong(
	                   (PY_LONG_LONG) offset );
#else
	argument_offset = PyLong_FromLongLong(
	                   (long) offset );
#endif
	argument_whence = PyInt_FromLong(
	                   (long) whence );

	PyErr_Clear();

	method_result = PyObject_CallMethodObjArgs(
	                 file_object,
	                 method_name,
	                 argument_offset,
	                 argument_whence,
	                 NULL );

	if( PyErr_Occurred() )
	{
		PyErr_Fetch(
		 &exception_type,
		 &exception_value,
		 &exception_traceback );

		exception_string = PyObject_Repr(
		                    exception_value );

		error_string = PyString_AsString(
		                exception_string );

		if( error_string != NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_SEEK_FAILED,
			 "%s: unable to seek in file object with error: %s.",
			 function,
			 error_string );
		}
		else
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_SEEK_FAILED,
			 "%s: unable to seek in file object.",
			 function );
		}
		Py_DecRef(
		 exception_string );

		goto on_error;
	}
	Py_DecRef(
	 method_result );

	Py_DecRef(
	 argument_whence );

	Py_DecRef(
	 argument_offset );

	Py_DecRef(
	 method_name );

	return( 1 );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( argument_whence != NULL )
	{
		Py_DecRef(
		 argument_whence );
	}
	if( argument_offset != NULL )
	{
		Py_DecRef(
		 argument_offset );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
示例#6
0
// Call a single slot and return the result.
PyObject *PyQtSlot::call(PyObject *callable, PyObject *args) const
{
    PyObject *sa, *oxtype, *oxvalue, *oxtb;

    // Keep some compilers quiet.
    oxtype = oxvalue = oxtb = 0;

    // We make repeated attempts to call a slot.  If we work out that it failed
    // because of an immediate type error we try again with one less argument.
    // We keep going until we run out of arguments to drop.  This emulates the
    // Qt ability of the slot to accept fewer arguments than a signal provides.
    sa = args;
    Py_INCREF(sa);

    for (;;)
    {
        PyObject *nsa, *xtype, *xvalue, *xtb, *res;

        if ((res = PyEval_CallObject(callable, sa)) != NULL)
        {
            // Remove any previous exception.

            if (sa != args)
            {
                Py_XDECREF(oxtype);
                Py_XDECREF(oxvalue);
                Py_XDECREF(oxtb);
                PyErr_Clear();
            }

            Py_DECREF(sa);

            return res;
        }

        // Get the exception.
        PyErr_Fetch(&xtype, &xvalue, &xtb);

        // See if it is unacceptable.  An acceptable failure is a type error
        // with no traceback - so long as we can still reduce the number of
        // arguments and try again.
        if (!PyErr_GivenExceptionMatches(xtype, PyExc_TypeError) || xtb ||
            PyTuple_Size(sa) == 0)
        {
            // If there is a traceback then we must have called the slot and
            // the exception was later on - so report the exception as is.
            if (xtb)
            {
                if (sa != args)
                {
                    Py_XDECREF(oxtype);
                    Py_XDECREF(oxvalue);
                    Py_XDECREF(oxtb);
                }

                PyErr_Restore(xtype,xvalue,xtb);
            }
            else if (sa == args)
            {
                PyErr_Restore(xtype, xvalue, xtb);
            }
            else
            {
                // Discard the latest exception and restore the original one.
                Py_XDECREF(xtype);
                Py_XDECREF(xvalue);
                Py_XDECREF(xtb);

                PyErr_Restore(oxtype, oxvalue, oxtb);
            }

            break;
        }

        // If this is the first attempt, save the exception.
        if (sa == args)
        {
            oxtype = xtype;
            oxvalue = xvalue;
            oxtb = xtb;
        }
        else
        {
            Py_XDECREF(xtype);
            Py_XDECREF(xvalue);
            Py_XDECREF(xtb);
        }

        // Create the new argument tuple.
        if ((nsa = PyTuple_GetSlice(sa, 0, PyTuple_Size(sa) - 1)) == NULL)
        {
            // Tidy up.
            Py_XDECREF(oxtype);
            Py_XDECREF(oxvalue);
            Py_XDECREF(oxtb);

            break;
        }

        Py_DECREF(sa);
        sa = nsa;
    }

    Py_DECREF(sa);

    return 0;
}
/* Retrieves the current offset within the file object
 * Make sure to hold the GIL state before calling this function
 * Returns 1 if successful or -1 on error
 */
int pyewf_file_object_get_offset(
     PyObject *file_object,
     off64_t *offset,
     libcerror_error_t **error )
{
	PyObject *exception_string    = NULL;
	PyObject *exception_traceback = NULL;
	PyObject *exception_type      = NULL;
	PyObject *exception_value     = NULL;
	PyObject *method_name         = NULL;
	PyObject *method_result       = NULL;
	char *error_string            = NULL;
	static char *function         = "pyewf_file_object_get_offset";
	int result                    = 0;

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( offset == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid offset.",
		 function );

		return( -1 );
	}
	method_name = PyString_FromString(
	               "get_offset" );

	PyErr_Clear();

	/* Determine if the file object has the get_offset method
	 */
	result = PyObject_HasAttr(
	          file_object,
	          method_name );

	if( result == 0 )
	{
		Py_DecRef(
		 method_name );

		/* Fall back to the tell method
		 */
		method_name = PyString_FromString(
		               "tell" );
	}
	PyErr_Clear();

	method_result = PyObject_CallMethodObjArgs(
	                 file_object,
	                 method_name,
	                 NULL );

	if( PyErr_Occurred() )
	{
		PyErr_Fetch(
		 &exception_type,
		 &exception_value,
		 &exception_traceback );

		exception_string = PyObject_Repr(
		                    exception_value );

		error_string = PyString_AsString(
		                exception_string );

		if( error_string != NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve current offset in file object with error: %s.",
			 function,
			 error_string );
		}
		else
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve current offset in file object.",
			 function );
		}
		Py_DecRef(
		 exception_string );

		goto on_error;
	}
	if( pyewf_integer_signed_copy_to_64bit(
	     method_result,
	     offset,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to convert method result into current offset of file object.",
		 function );

		goto on_error;
	}
	Py_DecRef(
	 method_result );

	Py_DecRef(
	 method_name );

	return( 1 );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
示例#8
0
static int
profiler_callback(PyObject *self, PyFrameObject *frame, int what,
                  PyObject *arg)
{
    ProfilerObject *pObj = (ProfilerObject*)self;
    {
        /* keep error state, see ptrace_enter_call above.
         * We could keep this more focused, only really needed
         * when calling a user time function, and initializing
         * a user object
         */
        PyObject *et, *ev, *tb;
        PyErr_Fetch(&et, &ev, &tb);
        pObj->currentTime = CALL_TIMER(pObj);
        SelectStack(pObj);
        PyErr_Restore(et, ev, tb);
    }
    if (pObj->currentProfilerStack == NULL)
        return 0;

    switch (what) {

    /* the 'frame' of a called function is about to start its execution */
    case PyTrace_CALL:
        ptrace_enter_call(self, (void *)frame->f_code,
                                (PyObject *)frame->f_code);
        break;

    /* the 'frame' of a called function is about to finish
       (either normally or with an exception) */
    case PyTrace_RETURN:
        ptrace_leave_call(self, (void *)frame->f_code);
        break;

    /* case PyTrace_EXCEPTION:
        If the exception results in the function exiting, a
        PyTrace_RETURN event will be generated, so we don't need to
        handle it. */

#ifdef PyTrace_C_CALL   /* not defined in Python <= 2.3 */
    /* the Python function 'frame' is issuing a call to the built-in
       function 'arg' */
    case PyTrace_C_CALL:
        if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
            && PyCFunction_Check(arg)) {
            ptrace_enter_call(self,
                              ((PyCFunctionObject *)arg)->m_ml,
                              arg);
        }
        break;

    /* the call to the built-in function 'arg' is returning into its
       caller 'frame' */
    case PyTrace_C_RETURN:              /* ...normally */
    case PyTrace_C_EXCEPTION:           /* ...with an exception set */
        if ((((ProfilerObject *)self)->flags & POF_BUILTINS)
            && PyCFunction_Check(arg)) {
            ptrace_leave_call(self,
                              ((PyCFunctionObject *)arg)->m_ml);
        }
        break;
#endif

    default:
        break;
    }
    return 0;
}
示例#9
0
bool PythonScript::execute(TWScriptAPI *tw) const
{
    PyObject * tmp;

    // Load the script
    QFile scriptFile(m_Filename);
    if (!scriptFile.open(QIODevice::ReadOnly)) {
        // handle error
        return false;
    }
    QString contents = m_Codec->toUnicode(scriptFile.readAll());
    scriptFile.close();

    // Python seems to require Unix style line endings
    if (contents.contains("\r"))
        contents.replace(QRegExp("\r\n?"), "\n");

    // Create a separate sub-interpreter for this script
    PyThreadState* interpreter = Py_NewInterpreter();

    // Register the types
    if (!registerPythonTypes(tw->GetResult())) {
        Py_EndInterpreter(interpreter);
        return false;
    }

    pyQObject *TW;

    TW = (pyQObject*)QObjectToPython(tw);
    if (!TW) {
        tw->SetResult(tr("Could not create TW"));
        Py_EndInterpreter(interpreter);
        return false;
    }

    // Run the script
    PyObject * globals, * locals;
    globals = PyDict_New();
    locals = PyDict_New();

    // Create a dictionary of global variables
    // without the __builtins__ module, nothing would work!
    PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins());
    PyDict_SetItemString(globals, "TW", (PyObject*)TW);

    PyObject * ret = NULL;

    if (globals && locals)
        ret = PyRun_String(qPrintable(contents), Py_file_input, globals, locals);

    Py_XDECREF(globals);
    Py_XDECREF(locals);
    Py_XDECREF(ret);
    Py_XDECREF(TW);

    // Check for exceptions
    if (PyErr_Occurred()) {
        PyObject * errType, * errValue, * errTraceback;
        PyErr_Fetch(&errType, &errValue, &errTraceback);

        tmp = PyObject_Str(errValue);
        QString errString;
        if (!asQString(tmp, errString)) {
            Py_XDECREF(tmp);
            tw->SetResult(tr("Unknown error"));
            return false;
        }
        Py_XDECREF(tmp);
        tw->SetResult(errString);

        /////////////////////DEBUG
        // This prints the python error in the usual python way to stdout
        // Simply comment this block to prevent this behavior
        Py_XINCREF(errType);
        Py_XINCREF(errValue);
        Py_XINCREF(errTraceback);
        PyErr_Restore(errType, errValue, errTraceback);
        PyErr_Print();
        /////////////////////DEBUG

        Py_XDECREF(errType);
        Py_XDECREF(errValue);
        Py_XDECREF(errTraceback);

        Py_EndInterpreter(interpreter);
        return false;
    }

    // Finish
    Py_EndInterpreter(interpreter);
    return true;
}
示例#10
0
// Format the current Python exception as a string.
// Let Python do the work for us; call traceback.format_exception()
std::string formatPythonException() {
    if (!PyErr_Occurred()) {
        return "<no error?>";
    }

    // Retrieve Python exception and "normalize" (the docs are unclear but
    // they say you should do it :) )
    PyObject* exceptionObj;
    PyObject* valueObj;
    PyObject* tracebackObj;
    PyErr_Fetch(&exceptionObj, &valueObj, &tracebackObj);
    DCHECK(exceptionObj);
    PyErr_NormalizeException(&exceptionObj, &valueObj, &tracebackObj);

    PyObjectHandle exception(exceptionObj);
    PyObjectHandle value(valueObj);
    PyObjectHandle traceback(tracebackObj);

    // value and traceback may be null
    if (!value) {
        value.reset(PyObjectHandle::INCREF, Py_None);
    }
    if (!traceback) {
        traceback.reset(PyObjectHandle::INCREF, Py_None);
    }

    PyObjectHandle tbModule(PyImport_ImportModule("traceback"));
    if (!tbModule) {
        return "<import traceback failed>";
    }

    PyObject* tbDict = PyModule_GetDict(tbModule.get());  // borrowed
    if (!tbDict) {
        return "<no dict in traceback module>";
    }

    // borrowed
    PyObject* formatFunc = PyDict_GetItemString(tbDict, "format_exception");
    if (!formatFunc) {
        return "<no format_exception in traceback module>";
    }

    PyObjectHandle formatted(PyObject_CallFunction(
                                 formatFunc, const_cast<char*>("OOO"), exception.get(), value.get(),
                                 traceback.get()));
    if (!formatted) {
        return "<traceback.format_exception error>";
    }

    // format_exception returns a list of strings that should be concatenated.
    // Well then, let's do that.

    if (!PyList_Check(formatted.get())) {
        return "<traceback.format_exception didn't return a list>";
    }

    std::string out;
    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(formatted.get()); ++i) {
        PyObject* obj = PyList_GET_ITEM(formatted.get(), i);  // borrowed
        char* data;
        Py_ssize_t len;
        if (PyString_AsStringAndSize(obj, &data, &len) == -1) {
            return "<traceback.format_exception member not a string>";
        }
        out.append(data, len);
    }

    return out;
}
示例#11
0
/* Fetches an error
 */
void VARARGS(
      pyesedb_error_fetch,
      libcerror_error_t **error,
      int error_domain,
      int error_code,
      const char *,
      format_string )
{
	va_list argument_list;

	char error_string[ PYESEDB_ERROR_STRING_SIZE ];

        PyObject *exception_traceback = NULL;
        PyObject *exception_type      = NULL;
        PyObject *exception_value     = NULL;
        PyObject *string_object       = NULL;
	static char *function         = "pyesedb_error_fetch";
	char *exception_string        = NULL;
	size_t error_string_length    = 0;
	int print_count               = 0;

#if PY_MAJOR_VERSION >= 3
	PyObject *utf8_string_object  = NULL;
#endif

	if( format_string == NULL )
	{
		PyErr_Format(
		 PyExc_ValueError,
		 "%s: missing format string.",
		 function );

		return;
	}
	VASTART(
	 argument_list,
	 const char *,
	 format_string );

	print_count = PyOS_vsnprintf(
	               error_string,
	               PYESEDB_ERROR_STRING_SIZE,
	               format_string,
	               argument_list );

	VAEND(
	 argument_list );

	if( print_count < 0 )
	{
		PyErr_Format(
		 PyExc_ValueError,
		 "%s: unable to format error string.",
		 function );

		return;
	}
	error_string_length = libcstring_narrow_string_length(
	                       error_string );

	if( ( error_string_length >= 1 )
	 && ( error_string[ error_string_length - 1 ] == '.' ) )
	{
		error_string[ error_string_length - 1 ] = 0;
	}
	PyErr_Fetch(
	 &exception_type,
	 &exception_value,
	 &exception_traceback );

	string_object = PyObject_Repr(
	                 exception_value );

#if PY_MAJOR_VERSION >= 3
	utf8_string_object = PyUnicode_AsUTF8String(
	                      string_object );

	if( utf8_string_object != NULL )
	{
		exception_string = PyBytes_AsString(
		                    utf8_string_object );
	}
#else
	exception_string = PyString_AsString(
	                    string_object );
#endif
	if( exception_string != NULL )
	{
		libcerror_error_set(
		 error,
		 error_domain,
		 error_code,
		 "%s with error: %s.",
		 error_string,
		 exception_string );
	}
	else
	{
		libcerror_error_set(
		 error,
		 error_domain,
		 error_code,
		 "%s.",
		 error_string );
	}
#if PY_MAJOR_VERSION >= 3
	if( utf8_string_object != NULL )
	{
		Py_DecRef(
		 utf8_string_object );
	}
#endif
	Py_DecRef(
	 string_object );

	return;
}
示例#12
0
static varobj_item *
py_varobj_iter_next (struct varobj_iter *self)
{
  struct py_varobj_iter *t = (struct py_varobj_iter *) self;
  struct cleanup *back_to;
  PyObject *item;
  PyObject *py_v;
  varobj_item *vitem;
  const char *name = NULL;

  if (!gdb_python_initialized)
    return NULL;

  back_to = varobj_ensure_python_env (self->var);

  item = PyIter_Next (t->iter);

  if (item == NULL)
    {
      /* Normal end of iteration.  */
      if (!PyErr_Occurred ())
	return NULL;

      /* If we got a memory error, just use the text as the item.  */
      if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
	{
	  PyObject *type, *value, *trace;
	  char *name_str, *value_str;

	  PyErr_Fetch (&type, &value, &trace);
	  value_str = gdbpy_exception_to_string (type, value);
	  Py_XDECREF (type);
	  Py_XDECREF (value);
	  Py_XDECREF (trace);
	  if (value_str == NULL)
	    {
	      gdbpy_print_stack ();
	      return NULL;
	    }

	  name_str = xstrprintf ("<error at %d>",
				 self->next_raw_index++);
	  item = Py_BuildValue ("(ss)", name_str, value_str);
	  xfree (name_str);
	  xfree (value_str);
	  if (item == NULL)
	    {
	      gdbpy_print_stack ();
	      return NULL;
	    }
	}
      else
	{
	  /* Any other kind of error.  */
	  gdbpy_print_stack ();
	  return NULL;
	}
    }

  if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
    {
      gdbpy_print_stack ();
      error (_("Invalid item from the child list"));
    }

  vitem = XNEW (struct varobj_item);
  vitem->value = convert_value_from_python (py_v);
  if (vitem->value == NULL)
    gdbpy_print_stack ();
  vitem->name = xstrdup (name);

  self->next_raw_index++;
  do_cleanups (back_to);
  return vitem;
}
示例#13
0
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
    PyObject* owned_instance = NULL;
    if (tb == Py_None) {
        tb = 0;
    } else if (tb && !PyTraceBack_Check(tb)) {
        PyErr_SetString(PyExc_TypeError,
            "raise: arg 3 must be a traceback or None");
        goto bad;
    }
    if (value == Py_None)
        value = 0;

    if (PyExceptionInstance_Check(type)) {
        if (value) {
            PyErr_SetString(PyExc_TypeError,
                "instance exception may not have a separate value");
            goto bad;
        }
        value = type;
        type = (PyObject*) Py_TYPE(value);
    } else if (PyExceptionClass_Check(type)) {
        // make sure value is an exception instance of type
        PyObject *instance_class = NULL;
        if (value && PyExceptionInstance_Check(value)) {
            instance_class = (PyObject*) Py_TYPE(value);
            if (instance_class != type) {
                int is_subclass = PyObject_IsSubclass(instance_class, type);
                if (!is_subclass) {
                    instance_class = NULL;
                } else if (unlikely(is_subclass == -1)) {
                    // error on subclass test
                    goto bad;
                } else {
                    // believe the instance
                    type = instance_class;
                }
            }
        }
        if (!instance_class) {
            // instantiate the type now (we don't know when and how it will be caught)
            // assuming that 'value' is an argument to the type's constructor
            // not using PyErr_NormalizeException() to avoid ref-counting problems
            PyObject *args;
            if (!value)
                args = PyTuple_New(0);
            else if (PyTuple_Check(value)) {
                Py_INCREF(value);
                args = value;
            } else
                args = PyTuple_Pack(1, value);
            if (!args)
                goto bad;
            owned_instance = PyObject_Call(type, args, NULL);
            Py_DECREF(args);
            if (!owned_instance)
                goto bad;
            value = owned_instance;
            if (!PyExceptionInstance_Check(value)) {
                PyErr_Format(PyExc_TypeError,
                             "calling %R should have returned an instance of "
                             "BaseException, not %R",
                             type, Py_TYPE(value));
                goto bad;
            }
        }
    } else {
        PyErr_SetString(PyExc_TypeError,
            "raise: exception class must be a subclass of BaseException");
        goto bad;
    }

#if PY_VERSION_HEX >= 0x03030000
    if (cause) {
#else
    if (cause && cause != Py_None) {
#endif
        PyObject *fixed_cause;
        if (cause == Py_None) {
            // raise ... from None
            fixed_cause = NULL;
        } else if (PyExceptionClass_Check(cause)) {
            fixed_cause = PyObject_CallObject(cause, NULL);
            if (fixed_cause == NULL)
                goto bad;
        } else if (PyExceptionInstance_Check(cause)) {
            fixed_cause = cause;
            Py_INCREF(fixed_cause);
        } else {
            PyErr_SetString(PyExc_TypeError,
                            "exception causes must derive from "
                            "BaseException");
            goto bad;
        }
        PyException_SetCause(value, fixed_cause);
    }

    PyErr_SetObject(type, value);

    if (tb) {
#if CYTHON_COMPILING_IN_PYPY
        PyObject *tmp_type, *tmp_value, *tmp_tb;
        PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb);
        Py_INCREF(tb);
        PyErr_Restore(tmp_type, tmp_value, tb);
        Py_XDECREF(tmp_tb);
#else
        PyThreadState *tstate = PyThreadState_GET();
        PyObject* tmp_tb = tstate->curexc_traceback;
        if (tb != tmp_tb) {
            Py_INCREF(tb);
            tstate->curexc_traceback = tb;
            Py_XDECREF(tmp_tb);
        }
#endif
    }

bad:
    Py_XDECREF(owned_instance);
    return;
}
#endif

/////////////// GetException.proto ///////////////
//@substitute: naming
//@requires: PyThreadStateGet

#if CYTHON_FAST_THREAD_STATE
#define __Pyx_GetException(type, value, tb)  __Pyx__GetException($local_tstate_cname, type, value, tb)
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); /*proto*/
#else
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
#endif

/////////////// GetException ///////////////

#if CYTHON_FAST_THREAD_STATE
static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
#else
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
#endif
    PyObject *local_type, *local_value, *local_tb;
#if CYTHON_FAST_THREAD_STATE
    PyObject *tmp_type, *tmp_value, *tmp_tb;
    local_type = tstate->curexc_type;
    local_value = tstate->curexc_value;
    local_tb = tstate->curexc_traceback;
    tstate->curexc_type = 0;
    tstate->curexc_value = 0;
    tstate->curexc_traceback = 0;
#else
    PyErr_Fetch(&local_type, &local_value, &local_tb);
#endif
    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
#if CYTHON_FAST_THREAD_STATE
    if (unlikely(tstate->curexc_type))
#else
    if (unlikely(PyErr_Occurred()))
#endif
        goto bad;
    #if PY_MAJOR_VERSION >= 3
    if (local_tb) {
        if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
            goto bad;
    }
    #endif
    // traceback may be NULL for freshly raised exceptions
    Py_XINCREF(local_tb);
    // exception state may be temporarily empty in parallel loops (race condition)
    Py_XINCREF(local_type);
    Py_XINCREF(local_value);
    *type = local_type;
    *value = local_value;
    *tb = local_tb;
#if CYTHON_FAST_THREAD_STATE
    tmp_type = tstate->exc_type;
    tmp_value = tstate->exc_value;
    tmp_tb = tstate->exc_traceback;
    tstate->exc_type = local_type;
    tstate->exc_value = local_value;
    tstate->exc_traceback = local_tb;
    // Make sure tstate is in a consistent state when we XDECREF
    // these objects (DECREF may run arbitrary code).
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);
#else
    PyErr_SetExcInfo(local_type, local_value, local_tb);
#endif
    return 0;
bad:
    *type = 0;
    *value = 0;
    *tb = 0;
    Py_XDECREF(local_type);
    Py_XDECREF(local_value);
    Py_XDECREF(local_tb);
    return -1;
}

/////////////// ReRaiseException.proto ///////////////

static CYTHON_INLINE void __Pyx_ReraiseException(void); /*proto*/

/////////////// ReRaiseException.proto ///////////////

static CYTHON_INLINE void __Pyx_ReraiseException(void) {
    PyObject *type = NULL, *value = NULL, *tb = NULL;
#if CYTHON_FAST_THREAD_STATE
    PyThreadState *tstate = PyThreadState_GET();
    type = tstate->exc_type;
    value = tstate->exc_value;
    tb = tstate->exc_traceback;
#else
    PyErr_GetExcInfo(&type, &value, &tb);
#endif
    if (!type || type == Py_None) {
#if !CYTHON_FAST_THREAD_STATE
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(tb);
#endif
        // message copied from Py3
        PyErr_SetString(PyExc_RuntimeError,
            "No active exception to reraise");
    } else {
#if CYTHON_FAST_THREAD_STATE
        Py_INCREF(type);
        Py_XINCREF(value);
        Py_XINCREF(tb);

#endif
        PyErr_Restore(type, value, tb);
    }
}
示例#14
0
static PyObject *
gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
{
    PyThreadState *tstate = PyThreadState_GET();
    PyFrameObject *f = gen->gi_frame;
    PyObject *result;

    if (gen->gi_running) {
        char *msg = "generator already executing";
        if (PyCoro_CheckExact(gen))
            msg = "coroutine already executing";
        PyErr_SetString(PyExc_ValueError, msg);
        return NULL;
    }
    if (f == NULL || f->f_stacktop == NULL) {
        if (PyCoro_CheckExact(gen) && !closing) {
            /* `gen` is an exhausted coroutine: raise an error,
               except when called from gen_close(), which should
               always be a silent method. */
            PyErr_SetString(
                PyExc_RuntimeError,
                "cannot reuse already awaited coroutine");
        } else if (arg && !exc) {
            /* `gen` is an exhausted generator:
               only set exception if called from send(). */
            PyErr_SetNone(PyExc_StopIteration);
        }
        return NULL;
    }

    if (f->f_lasti == -1) {
        if (arg && arg != Py_None) {
            char *msg = "can't send non-None value to a "
                        "just-started generator";
            if (PyCoro_CheckExact(gen))
                msg = "can't send non-None value to a "
                      "just-started coroutine";
            PyErr_SetString(PyExc_TypeError, msg);
            return NULL;
        }
    } else {
        /* Push arg onto the frame's value stack */
        result = arg ? arg : Py_None;
        Py_INCREF(result);
        *(f->f_stacktop++) = result;
    }

    /* Generators always return to their most recent caller, not
     * necessarily their creator. */
    Py_XINCREF(tstate->frame);
    assert(f->f_back == NULL);
    f->f_back = tstate->frame;

    gen->gi_running = 1;
    result = PyEval_EvalFrameEx(f, exc);
    gen->gi_running = 0;

    /* Don't keep the reference to f_back any longer than necessary.  It
     * may keep a chain of frames alive or it could create a reference
     * cycle. */
    assert(f->f_back == tstate->frame);
    Py_CLEAR(f->f_back);

    /* If the generator just returned (as opposed to yielding), signal
     * that the generator is exhausted. */
    if (result && f->f_stacktop == NULL) {
        if (result == Py_None) {
            /* Delay exception instantiation if we can */
            PyErr_SetNone(PyExc_StopIteration);
        } else {
            PyObject *e = PyObject_CallFunctionObjArgs(
                               PyExc_StopIteration, result, NULL);
            if (e != NULL) {
                PyErr_SetObject(PyExc_StopIteration, e);
                Py_DECREF(e);
            }
        }
        Py_CLEAR(result);
    }
    else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) {
        /* Check for __future__ generator_stop and conditionally turn
         * a leaking StopIteration into RuntimeError (with its cause
         * set appropriately). */
        if (((PyCodeObject *)gen->gi_code)->co_flags &
              (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE))
        {
            PyObject *exc, *val, *val2, *tb;
            char *msg = "generator raised StopIteration";
            if (PyCoro_CheckExact(gen))
                msg = "coroutine raised StopIteration";
            PyErr_Fetch(&exc, &val, &tb);
            PyErr_NormalizeException(&exc, &val, &tb);
            if (tb != NULL)
                PyException_SetTraceback(val, tb);
            Py_DECREF(exc);
            Py_XDECREF(tb);
            PyErr_SetString(PyExc_RuntimeError, msg);
            PyErr_Fetch(&exc, &val2, &tb);
            PyErr_NormalizeException(&exc, &val2, &tb);
            Py_INCREF(val);
            PyException_SetCause(val2, val);
            PyException_SetContext(val2, val);
            PyErr_Restore(exc, val2, tb);
        }
        else {
            PyObject *exc, *val, *tb;

            /* Pop the exception before issuing a warning. */
            PyErr_Fetch(&exc, &val, &tb);

            if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
                                 "generator '%.50S' raised StopIteration",
                                 gen->gi_qualname)) {
                /* Warning was converted to an error. */
                Py_XDECREF(exc);
                Py_XDECREF(val);
                Py_XDECREF(tb);
            }
            else {
                PyErr_Restore(exc, val, tb);
            }
        }
    }

    if (!result || f->f_stacktop == NULL) {
        /* generator can't be rerun, so release the frame */
        /* first clean reference cycle through stored exception traceback */
        PyObject *t, *v, *tb;
        t = f->f_exc_type;
        v = f->f_exc_value;
        tb = f->f_exc_traceback;
        f->f_exc_type = NULL;
        f->f_exc_value = NULL;
        f->f_exc_traceback = NULL;
        Py_XDECREF(t);
        Py_XDECREF(v);
        Py_XDECREF(tb);
        gen->gi_frame->f_gen = NULL;
        gen->gi_frame = NULL;
        Py_DECREF(f);
    }

    return result;
}
示例#15
0
int
_PyIOBase_finalize(PyObject *self)
{
    PyObject *res;
    PyObject *tp, *v, *tb;
    int closed = 1;
    int is_zombie;

    /* If _PyIOBase_finalize() is called from a destructor, we need to
       resurrect the object as calling close() can invoke arbitrary code. */
    is_zombie = (Py_REFCNT(self) == 0);
    if (is_zombie) {
        ++Py_REFCNT(self);
    }
    PyErr_Fetch(&tp, &v, &tb);
    /* If `closed` doesn't exist or can't be evaluated as bool, then the
       object is probably in an unusable state, so ignore. */
    res = PyObject_GetAttr(self, _PyIO_str_closed);
    if (res == NULL)
        PyErr_Clear();
    else {
        closed = PyObject_IsTrue(res);
        Py_DECREF(res);
        if (closed == -1)
            PyErr_Clear();
    }
    if (closed == 0) {
        res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close,
                                          NULL);
        /* Silencing I/O errors is bad, but printing spurious tracebacks is
           equally as bad, and potentially more frequent (because of
           shutdown issues). */
        if (res == NULL)
            PyErr_Clear();
        else
            Py_DECREF(res);
    }
    PyErr_Restore(tp, v, tb);
    if (is_zombie) {
        if (--Py_REFCNT(self) != 0) {
            /* The object lives again. The following code is taken from
               slot_tp_del in typeobject.c. */
            Py_ssize_t refcnt = Py_REFCNT(self);
            _Py_NewReference(self);
            Py_REFCNT(self) = refcnt;
            /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
             * we need to undo that. */
            _Py_DEC_REFTOTAL;
            /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
             * chain, so no more to do there.
             * If COUNT_ALLOCS, the original decref bumped tp_frees, and
             * _Py_NewReference bumped tp_allocs:  both of those need to be
             * undone.
             */
#ifdef COUNT_ALLOCS
            --Py_TYPE(self)->tp_frees;
            --Py_TYPE(self)->tp_allocs;
#endif
            return -1;
        }
    }
    return 0;
}
示例#16
0
文件: py_plugin.c 项目: alama/cwiid
int py_plugin_open(struct plugin *plugin, char *dir)
{
	PyObject *handle, *info;
	PyObject *PyStr;
	PyObject *PyErrType, *PyErr, *PyTraceback;

	if (!(PyStr = PyString_FromString(dir))) {
		PyErr_Print();
		return -1;
	}

	if (PyList_Insert(PyPath, 0, PyStr)) {
		Py_DECREF(PyStr);
		return -1;
	}

	if (!(handle = PyImport_ImportModule(plugin->name))) {
		/* ignore "module not found" errors in top level module */
		PyErr_Fetch(&PyErrType, &PyErr, &PyTraceback);
		PyErr_NormalizeException(&PyErrType, &PyErr, &PyTraceback);
		if (PyErr_GivenExceptionMatches(PyErr, PyExc_ImportError) &&
		  !PyTraceback) {
			Py_XDECREF(PyErrType);
			Py_XDECREF(PyErr);
		}
		else {
			PyErr_Restore(PyErrType, PyErr, PyTraceback);
			PyErr_Print();
		}

		if (PySequence_DelItem(PyPath, 0)) {
			PyErr_Print();
		}
		Py_DECREF(PyStr);
		return -1;
	}

	if (PySequence_DelItem(PyPath, 0)) {
		PyErr_Print();
	}
	Py_DECREF(PyStr);

	if (!(plugin->p = malloc(sizeof(struct py_plugin)))) {
		wminput_err("Error allocating py_plugin");
		return -1;
	}

	plugin->type = PLUGIN_PYTHON;
	plugin->info = NULL;
	plugin->data = NULL;
	((struct py_plugin *) plugin->p)->init = NULL;
	((struct py_plugin *) plugin->p)->exec = NULL;

	if (!(plugin->info = malloc(sizeof *plugin->info))) {
		wminput_err("Error allocating plugin info");
		goto ERR_HND;
	}
	if (!(plugin->data = malloc(sizeof *plugin->data))) {
		wminput_err("Error allocating plugin data");
		goto ERR_HND;
	}
	if (!(((struct py_plugin *)plugin->p)->init =
	  PyObject_GetAttrString(handle, "wmplugin_init"))) {
		PyErr_Print();
		goto ERR_HND;
	}
	if (!PyCallable_Check(((struct py_plugin *)plugin->p)->init)) {
		wminput_err("Unable to load plugin init function: not callable");
		goto ERR_HND;
	}
	if (!(((struct py_plugin *)plugin->p)->exec =
	  PyObject_GetAttrString(handle, "wmplugin_exec"))) {
		PyErr_Print();
		goto ERR_HND;
	}
	if (!PyCallable_Check(((struct py_plugin *)plugin->p)->exec)) {
		wminput_err("Unable to load plugin exec function: not callable");
		goto ERR_HND;
	}
	if (!(info = PyObject_GetAttrString(handle, "wmplugin_info"))) {
		PyErr_Print();
		goto ERR_HND;
	}
	if (!PyCallable_Check(info)) {
		wminput_err("Unable to load plugin info function: not callable");
		Py_DECREF((PyObject *)info);
		goto ERR_HND;
	}
	if (py_plugin_info(plugin, info)) {
		wminput_err("Error on python_info");
		Py_DECREF((PyObject *)info);
		goto ERR_HND;
	}
	Py_DECREF((PyObject *)info);

	((struct py_plugin *) plugin->p)->handle = handle;

	return 0;

ERR_HND:
	if (plugin->info) {
		free(plugin->info);
	}
	if (plugin->data) {
		free(plugin->data);
	}
	if (plugin->p) {
		if (((struct py_plugin *)plugin->p)->init) {
			Py_DECREF(((struct py_plugin *)plugin->p)->init);
		}
		if (((struct py_plugin *)plugin->p)->exec) {
			Py_DECREF(((struct py_plugin *)plugin->p)->exec);
		}
		free(plugin->p);
	}
	Py_DECREF(handle);
	return -1;
}
示例#17
0
void python_handle_exception(const char *fmt, ...)
{
    PyObject *pResult;
    const char *msg;
    char *buf;
    size_t buflen, msglen;
    PyObject *exception, *v, *tb, *args;
    PyObject *line;
    int i;
    char *srcbuf;

    // We don't want to generate traceback when no errors occured
    if (!PyErr_Occurred())
	return;

    if (fmt == NULL)
	srcbuf = NULL;
    else
	srcbuf = make_message(fmt);

    PyErr_Fetch(&exception, &v, &tb);
    PyErr_Clear();
    if (exception == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, PyErr_Fetch() has failed.\n");
        return;
    }

    PyErr_NormalizeException(&exception, &v, &tb);
    if (exception == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, PyErr_NormalizeException() has failed.\n");
        return;
    }

    args = PyTuple_Pack(3, exception, v, tb ? tb : Py_None);
    Py_XDECREF(exception);
    Py_XDECREF(v);
    Py_XDECREF(tb);
    if (args == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, PyTuple_Pack() has failed.\n");
        return;
    }

    pResult = PyObject_CallObject(format_exc_obj, args);
    Py_DECREF(args);
    if (pResult == NULL) {
        LM_ERR("python_handle_exception(): Can't get traceback, traceback.format_exception() has failed.\n");
        return;
    }

    buflen = 1;
    buf = (char *)pkg_realloc(NULL, buflen * sizeof(char *));
    if (!buf)
    {
	LM_ERR("python_handle_exception(): Can't allocate memory (%lu bytes), pkg_realloc() has failed. Not enough memory.\n", buflen * sizeof(char *));
	return;
    }
    memset(buf, 0, sizeof(char *));

    for (i = 0; i < PySequence_Size(pResult); i++) {
        line = PySequence_GetItem(pResult, i);
        if (line == NULL) {
            LM_ERR("python_handle_exception(): Can't get traceback, PySequence_GetItem() has failed.\n");
            Py_DECREF(pResult);
	    if (buf)
		pkg_free(buf);
            return;
        }

        msg = PyString_AsString(line);

        if (msg == NULL) {
            LM_ERR("python_handle_exception(): Can't get traceback, PyString_AsString() has failed.\n");
            Py_DECREF(line);
            Py_DECREF(pResult);
	    if (buf)
		pkg_free(buf);
            return;
        }

	msglen = strlen(msg);
	buflen += ++msglen;

	buf = (char *)pkg_realloc(buf, buflen * sizeof(char *));
	if (!buf)
	{
	    LM_ERR("python_handle_exception(): Can't allocate memory (%li bytes), pkg_realloc() has failed. Not enough memory.\n", buflen * sizeof(char *));
	    Py_DECREF(line);
	    Py_DECREF(pResult);
	    return;
	}

	strncat(buf, msg, msglen >= buflen ? buflen-1 : msglen);

        Py_DECREF(line);
    }

    if (srcbuf == NULL)
	LM_ERR("Unhandled exception in the Python code:\n%s", buf);
    else
	LM_ERR("%s: Unhandled exception in the Python code:\n%s", srcbuf, buf);

    if (buf)
	pkg_free(buf);

    if (srcbuf)
	pkg_free(srcbuf);

    Py_DECREF(pResult);
}
示例#18
0
void reportPythonError( QString moduleName )
{
	// Print the Error
	if( PyErr_Occurred() )
	{
		PyObject *exception, *value, *traceback;

		PyErr_Fetch( &exception, &value, &traceback );
		PyErr_NormalizeException( &exception, &value, &traceback );

		// Set sys. variables for exception tracking
		PySys_SetObject( "last_type", exception );
		PySys_SetObject( "last_value", value );
		PySys_SetObject( "last_traceback", traceback );

		PyObject *exceptionName = PyObject_GetAttrString( exception, "__name__" );

		// Do we have a detailed description of the error ?
		PyObject *error = value != 0 ? PyObject_Str( value ) : 0;

		if( !error )
		{
			if( !moduleName.isNull() )
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured while compiling \"%1\": %2" ).arg( moduleName ).arg( PyString_AsString( exceptionName ) ) );
			}
			else
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured: %1" ).arg( PyString_AsString( exceptionName ) ) );
			}
		}
		else
		{
			if( !moduleName.isNull() )
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured in \"%1\": %2" ).arg( moduleName ).arg( PyString_AsString( exceptionName ) ) );
			}
			else
			{
				Console::instance()->log( LOG_ERROR, QString( "An error occured: %1" ).arg( PyString_AsString( exceptionName ) ) );
			}

			Console::instance()->log( LOG_PYTHON, QString( "%1: %2" ).arg( PyString_AsString( exceptionName ) ).arg( PyString_AsString( error ) ), false );
			Py_XDECREF( error );
		}

		// Don't print a traceback for syntax errors
		if( PyErr_GivenExceptionMatches( exception, PyExc_SyntaxError ) )
		{
			Py_XDECREF( traceback );
			traceback = 0;
		}

		// Dump a traceback
		while( traceback )
		{
			if( !PyObject_HasAttrString( traceback, "tb_frame" ) )
				break;

			PyObject *frame = PyObject_GetAttrString( traceback, "tb_frame" );

			if( !PyObject_HasAttrString( frame, "f_code" ) )
			{
				Py_XDECREF( frame );
				break;
			}

			PyObject *code = PyObject_GetAttrString( frame, "f_code" );

			if( !PyObject_HasAttrString( code, "co_filename" ) || !PyObject_HasAttrString( code, "co_name" ) )
			{
				Py_XDECREF( frame );
				Py_XDECREF( code );
				break;
			}

			PyObject *pyFilename = PyObject_GetAttrString( code, "co_filename" );
			PyObject *pyFunction = PyObject_GetAttrString( code, "co_name" );

			QString filename = PyString_AsString( pyFilename );
			QString function = PyString_AsString( pyFunction );

			Py_XDECREF( pyFilename );
			Py_XDECREF( pyFunction );

			Py_XDECREF( code );
			Py_XDECREF( frame );

			PyObject *pyLine = PyObject_GetAttrString( traceback, "tb_lineno" );
			unsigned int line = PyInt_AsLong( pyLine );
			Py_XDECREF( pyLine );

			// Print it 
			Console::instance()->log( LOG_PYTHON, QString( "File '%1',%2 in '%3'" ).arg( filename ).arg( line ).arg( function ), false );

			// Switch Frames
			PyObject *newtb = PyObject_GetAttrString( traceback, "tb_next" );
			Py_XDECREF( traceback );
			traceback = newtb;
		}

		Py_XDECREF( exceptionName );
		Py_XDECREF( exception );
		Py_XDECREF( value );
		Py_XDECREF( traceback );
	}
}
示例#19
0
文件: cjsonx.c 项目: petronius/cjsonx
static PyObject*
decode_string(JSONData *jsondata)
{
    PyObject *object;
    int c, escaping, has_unicode, string_escape;
    Py_ssize_t len;
    char *ptr;

    // look for the closing quote
    escaping = has_unicode = string_escape = False;
    ptr = jsondata->ptr + 1;
    while (True) {
        c = *ptr;
        if (c == 0) {
            PyErr_Format(JSON_DecodeError,
                         "unterminated string starting at position " SSIZE_T_F,
                         (Py_ssize_t)(jsondata->ptr - jsondata->str));
            return NULL;
        }
        if (!escaping) {
            if (c == '\\') {
                escaping = True;
            } else if (c == '"') {
                break;
            } else if (!isascii(c)) {
                has_unicode = True;
            }
        } else {
            switch(c) {
            case 'u':
                has_unicode = True;
                break;
            case '"':
            case 'r':
            case 'n':
            case 't':
            case 'b':
            case 'f':
            case '\\':
                string_escape = True;
                break;
            }
            escaping = False;
        }
        ptr++;
    }

    len = ptr - jsondata->ptr - 1;

    if (has_unicode || jsondata->all_unicode)
        object = PyUnicode_DecodeUnicodeEscape(jsondata->ptr+1, len, NULL);
    else if (string_escape)
        object = PyString_DecodeEscape(jsondata->ptr+1, len, NULL, 0, NULL);
    else
        object = PyString_FromStringAndSize(jsondata->ptr+1, len);

    if (object == NULL) {
        PyObject *type, *value, *tb, *reason;

        PyErr_Fetch(&type, &value, &tb);
        if (type == NULL) {
            PyErr_Format(JSON_DecodeError,
                         "invalid string starting at position " SSIZE_T_F,
                         (Py_ssize_t)(jsondata->ptr - jsondata->str));
        } else {
            if (PyErr_GivenExceptionMatches(type, PyExc_UnicodeDecodeError)) {
                reason = PyObject_GetAttrString(value, "reason");
                PyErr_Format(JSON_DecodeError, "cannot decode string starting"
                             " at position " SSIZE_T_F ": %s",
                             (Py_ssize_t)(jsondata->ptr - jsondata->str),
                             reason ? PyString_AsString(reason) : "bad format");
                Py_XDECREF(reason);
            } else {
                PyErr_Format(JSON_DecodeError,
                             "invalid string starting at position " SSIZE_T_F,
                             (Py_ssize_t)(jsondata->ptr - jsondata->str));
            }
        }
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(tb);
    } else {
        jsondata->ptr = ptr+1;
    }

    return object;
}
示例#20
0
void XBPyThread::Process()
{
  CLog::Log(LOGDEBUG,"Python thread: start processing");

  int m_Py_file_input = Py_file_input;

  // get the global lock
  PyEval_AcquireLock();
  PyThreadState* state = Py_NewInterpreter();
  if (!state)
  {
    PyEval_ReleaseLock();
    CLog::Log(LOGERROR,"Python thread: FAILED to get thread state!");
    return;
  }
  // swap in my thread state
  PyThreadState_Swap(state);

  m_pExecuter->InitializeInterpreter();

  CLog::Log(LOGDEBUG, "%s - The source file to load is %s", __FUNCTION__, m_source);

  // get path from script file name and add python path's
  // this is used for python so it will search modules from script path first
  CStdString scriptDir;
  URIUtils::GetDirectory(_P(m_source), scriptDir);
  URIUtils::RemoveSlashAtEnd(scriptDir);
  CStdString path = scriptDir;

  // add on any addon modules the user has installed
  ADDON::VECADDONS addons;
  ADDON::CAddonMgr::Get().GetAddons(ADDON::ADDON_SCRIPT_MODULE, addons);
  for (unsigned int i = 0; i < addons.size(); ++i)
    path += PY_PATH_SEP + _P(addons[i]->LibPath());

  // and add on whatever our default path is
  path += PY_PATH_SEP;

  {
    // we want to use sys.path so it includes site-packages
    // if this fails, default to using Py_GetPath
    PyObject *sysMod(PyImport_ImportModule((char*)"sys")); // must call Py_DECREF when finished
    PyObject *sysModDict(PyModule_GetDict(sysMod)); // borrowed ref, no need to delete
    PyObject *pathObj(PyDict_GetItemString(sysModDict, "path")); // borrowed ref, no need to delete

    if( pathObj && PyList_Check(pathObj) )
    {
      for( int i = 0; i < PyList_Size(pathObj); i++ )
      {
        PyObject *e = PyList_GetItem(pathObj, i); // borrowed ref, no need to delete
        if( e && PyString_Check(e) )
        {
            path += PyString_AsString(e); // returns internal data, don't delete or modify
            path += PY_PATH_SEP;
        }
      }
    }
    else
    {
      path += Py_GetPath();
    }
    Py_DECREF(sysMod); // release ref to sysMod
  }

  // set current directory and python's path.
  if (m_argv != NULL)
    PySys_SetArgv(m_argc, m_argv);

  CLog::Log(LOGDEBUG, "%s - Setting the Python path to %s", __FUNCTION__, path.c_str());

  PySys_SetPath((char *)path.c_str());

  CLog::Log(LOGDEBUG, "%s - Entering source directory %s", __FUNCTION__, scriptDir.c_str());

  PyObject* module = PyImport_AddModule((char*)"__main__");
  PyObject* moduleDict = PyModule_GetDict(module);

  // when we are done initing we store thread state so we can be aborted
  PyThreadState_Swap(NULL);
  PyEval_ReleaseLock();

  // we need to check if we was asked to abort before we had inited
  bool stopping = false;
  { CSingleLock lock(m_pExecuter->m_critSection);
    m_threadState = state;
    stopping = m_stopping;
  }

  PyEval_AcquireLock();
  PyThreadState_Swap(state);

  if (!stopping)
  {
    if (m_type == 'F')
    {
      // run script from file
      // We need to have python open the file because on Windows the DLL that python
      //  is linked against may not be the DLL that xbmc is linked against so 
      //  passing a FILE* to python from an fopen has the potential to crash.
      PyObject* file = PyFile_FromString((char *) _P(m_source).c_str(), (char*)"r");
      FILE *fp = PyFile_AsFile(file);

      if (fp)
      {
        PyObject *f = PyString_FromString(_P(m_source).c_str());
        PyDict_SetItemString(moduleDict, "__file__", f);
        Py_DECREF(f);
        PyRun_File(fp, _P(m_source).c_str(), m_Py_file_input, moduleDict, moduleDict);

        // Get a reference to the main module
        // and global dictionary
        PyObject* main_module = PyImport_AddModule((char*)"__main__");
        PyObject* global_dict = PyModule_GetDict(main_module);

        // Extract a reference to the function "func_name"
        // from the global dictionary
        PyObject* expression = PyDict_GetItemString(global_dict, "xbmcclosefilehack");

        if (!PyObject_CallFunction(expression,(char*)"(O)",file))
          CLog::Log(LOGERROR,"Failed to close the script file %s",_P(m_source).c_str());
      }
      else
        CLog::Log(LOGERROR, "%s not found!", m_source);
    }
    else
    {
      //run script
      PyRun_String(m_source, m_Py_file_input, moduleDict, moduleDict);
    }
  }

  if (!PyErr_Occurred())
    CLog::Log(LOGINFO, "Scriptresult: Success");
  else if (PyErr_ExceptionMatches(PyExc_SystemExit))
    CLog::Log(LOGINFO, "Scriptresult: Aborted");
  else
  {
    PyObject* exc_type;
    PyObject* exc_value;
    PyObject* exc_traceback;
    PyObject* pystring;
    pystring = NULL;

    PyErr_Fetch(&exc_type, &exc_value, &exc_traceback);
    if (exc_type == 0 && exc_value == 0 && exc_traceback == 0)
    {
      CLog::Log(LOGINFO, "Strange: No Python exception occured");
    }
    else
    {
      if (exc_type != NULL && (pystring = PyObject_Str(exc_type)) != NULL && (PyString_Check(pystring)))
      {
          PyObject *tracebackModule;

          CLog::Log(LOGINFO, "-->Python script returned the following error<--");
          CLog::Log(LOGERROR, "Error Type: %s", PyString_AsString(PyObject_Str(exc_type)));
          if (PyObject_Str(exc_value))
            CLog::Log(LOGERROR, "Error Contents: %s", PyString_AsString(PyObject_Str(exc_value)));

          tracebackModule = PyImport_ImportModule((char*)"traceback");
          if (tracebackModule != NULL)
          {
            PyObject *tbList, *emptyString, *strRetval;

            tbList = PyObject_CallMethod(tracebackModule, (char*)"format_exception", (char*)"OOO", exc_type, exc_value == NULL ? Py_None : exc_value, exc_traceback == NULL ? Py_None : exc_traceback);
            emptyString = PyString_FromString("");
            strRetval = PyObject_CallMethod(emptyString, (char*)"join", (char*)"O", tbList);

            CLog::Log(LOGERROR, "%s", PyString_AsString(strRetval));

            Py_DECREF(tbList);
            Py_DECREF(emptyString);
            Py_DECREF(strRetval);
            Py_DECREF(tracebackModule);
          }
          CLog::Log(LOGINFO, "-->End of Python script error report<--");
      }
      else
      {
        pystring = NULL;
        CLog::Log(LOGINFO, "<unknown exception type>");
      }

      CGUIDialogKaiToast *pDlgToast = (CGUIDialogKaiToast*)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST);
      if (pDlgToast)
      {
        CStdString desc;
        CStdString path;
        CStdString script;
        URIUtils::Split(m_source, path, script);
        if (script.Equals("default.py"))
        {
          CStdString path2;
          URIUtils::RemoveSlashAtEnd(path);
          URIUtils::Split(path, path2, script);
        }

        desc.Format(g_localizeStrings.Get(2100), script);
        pDlgToast->QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(257), desc);
      }
    }

    Py_XDECREF(exc_type);
    Py_XDECREF(exc_value); // caller owns all 3
    Py_XDECREF(exc_traceback); // already NULL'd out
    Py_XDECREF(pystring);
  }

  PyObject *m = PyImport_AddModule((char*)"xbmc");
  if(!m || PyObject_SetAttrString(m, (char*)"abortRequested", PyBool_FromLong(1)))
    CLog::Log(LOGERROR, "Scriptresult: failed to set abortRequested");

  // make sure all sub threads have finished
  for(PyThreadState* s = state->interp->tstate_head, *old = NULL; s;)
  {
    if(s == state)
    {
      s = s->next;
      continue;
    }
    if(old != s)
    {
      CLog::Log(LOGINFO, "Scriptresult: Waiting on thread %"PRIu64, (uint64_t)s->thread_id);
      old = s;
    }

    CPyThreadState pyState;
    Sleep(100);
    pyState.Restore();

    s = state->interp->tstate_head;
  }

  // pending calls must be cleared out
  PyXBMC_ClearPendingCalls(state);

  PyThreadState_Swap(NULL);
  PyEval_ReleaseLock();

  { CSingleLock lock(m_pExecuter->m_critSection);
    m_threadState = NULL;
  }

  PyEval_AcquireLock();
  PyThreadState_Swap(state);

  m_pExecuter->DeInitializeInterpreter();

  Py_EndInterpreter(state);
  PyThreadState_Swap(NULL);

  PyEval_ReleaseLock();
}
/* Retrieves the size of the file object
 * Make sure to hold the GIL state before calling this function
 * Returns 1 if successful or -1 on error
 */
int pyewf_file_object_get_size(
     PyObject *file_object,
     size64_t *size,
     libcerror_error_t **error )
{
	PyObject *exception_string    = NULL;
	PyObject *exception_traceback = NULL;
	PyObject *exception_type      = NULL;
	PyObject *exception_value     = NULL;
	PyObject *method_name         = NULL;
	PyObject *method_result       = NULL;
	char *error_string            = NULL;
	static char *function         = "pyewf_file_object_get_size";

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( size == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid size.",
		 function );

		return( -1 );
	}
	method_name = PyString_FromString(
	               "get_size" );

	PyErr_Clear();

	method_result = PyObject_CallMethodObjArgs(
	                 file_object,
	                 method_name,
	                 NULL );

	if( PyErr_Occurred() )
	{
		PyErr_Fetch(
		 &exception_type,
		 &exception_value,
		 &exception_traceback );

		exception_string = PyObject_Repr(
		                    exception_value );

		error_string = PyString_AsString(
		                exception_string );

		if( error_string != NULL )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve size of file object with error: %s.",
			 function,
			 error_string );
		}
		else
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve size of file object.",
			 function );
		}
		Py_DecRef(
		 exception_string );

		goto on_error;
	}
	if( pyewf_integer_unsigned_copy_to_64bit(
	     method_result,
	     size,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to convert method result into size of file object.",
		 function );

		goto on_error;
	}
	Py_DecRef(
	 method_result );

	Py_DecRef(
	 method_name );

	return( 1 );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
static void
err_input(perrdetail *err)
{
    PyObject *v, *w, *errtype, *errtext;
    PyObject *msg_obj = NULL;
    char *msg = NULL;
    int offset = err->offset;

    errtype = PyExc_SyntaxError;
    switch (err->error) {
    case E_ERROR:
        return;
    case E_SYNTAX:
        errtype = PyExc_IndentationError;
        if (err->expected == INDENT)
            msg = "expected an indented block";
        else if (err->token == INDENT)
            msg = "unexpected indent";
        else if (err->token == DEDENT)
            msg = "unexpected unindent";
        else {
            errtype = PyExc_SyntaxError;
            msg = "invalid syntax";
        }
        break;
    case E_TOKEN:
        msg = "invalid token";
        break;
    case E_EOFS:
        msg = "EOF while scanning triple-quoted string literal";
        break;
    case E_EOLS:
        msg = "EOL while scanning string literal";
        break;
    case E_INTR:
        if (!PyErr_Occurred())
            PyErr_SetNone(PyExc_KeyboardInterrupt);
        goto cleanup;
    case E_NOMEM:
        PyErr_NoMemory();
        goto cleanup;
    case E_EOF:
        msg = "unexpected EOF while parsing";
        break;
    case E_TABSPACE:
        errtype = PyExc_TabError;
        msg = "inconsistent use of tabs and spaces in indentation";
        break;
    case E_OVERFLOW:
        msg = "expression too long";
        break;
    case E_DEDENT:
        errtype = PyExc_IndentationError;
        msg = "unindent does not match any outer indentation level";
        break;
    case E_TOODEEP:
        errtype = PyExc_IndentationError;
        msg = "too many levels of indentation";
        break;
    case E_DECODE: {
        PyObject *type, *value, *tb;
        PyErr_Fetch(&type, &value, &tb);
        msg = "unknown decode error";
        if (value != NULL)
            msg_obj = PyObject_Str(value);
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(tb);
        break;
    }
    case E_LINECONT:
        msg = "unexpected character after line continuation character";
        break;

    case E_IDENTIFIER:
        msg = "invalid character in identifier";
        break;
    case E_BADSINGLE:
        msg = "multiple statements found while compiling a single statement";
        break;
    default:
        fprintf(stderr, "error=%d\n", err->error);
        msg = "unknown parsing error";
        break;
    }
    /* err->text may not be UTF-8 in case of decoding errors.
       Explicitly convert to an object. */
    if (!err->text) {
        errtext = Py_None;
        Py_INCREF(Py_None);
    } else {
        errtext = PyUnicode_DecodeUTF8(err->text, err->offset,
                                       "replace");
        if (errtext != NULL) {
            Py_ssize_t len = strlen(err->text);
            offset = (int)PyUnicode_GET_LENGTH(errtext);
            if (len != err->offset) {
                Py_DECREF(errtext);
                errtext = PyUnicode_DecodeUTF8(err->text, len,
                                               "replace");
            }
        }
    }
    v = Py_BuildValue("(OiiN)", err->filename,
                      err->lineno, offset, errtext);
    if (v != NULL) {
        if (msg_obj)
            w = Py_BuildValue("(OO)", msg_obj, v);
        else
            w = Py_BuildValue("(sO)", msg, v);
    } else
        w = NULL;
    Py_XDECREF(v);
    PyErr_SetObject(errtype, w);
    Py_XDECREF(w);
cleanup:
    Py_XDECREF(msg_obj);
    if (err->text != NULL) {
        PyObject_FREE(err->text);
        err->text = NULL;
    }
}
/* Writes a buffer to the file object
 * Make sure to hold the GIL state before calling this function
 * Returns the number of bytes written if successful, or -1 on error
 */
ssize_t pyewf_file_object_write_buffer(
         PyObject *file_object,
         const uint8_t *buffer,
         size_t size,
         libcerror_error_t **error )
{
	PyObject *argument_string     = NULL;
	PyObject *exception_string    = NULL;
	PyObject *exception_traceback = NULL;
	PyObject *exception_type      = NULL;
	PyObject *exception_value     = NULL;
	PyObject *method_name         = NULL;
	PyObject *method_result       = NULL;
	char *error_string            = NULL;
	static char *function         = "pyewf_file_object_write_buffer";

	if( file_object == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file object.",
		 function );

		return( -1 );
	}
	if( buffer == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid buffer.",
		 function );

		return( -1 );
	}
#if SIZEOF_SIZE_T > SIZEOF_INT
	if( size > (size_t) INT_MAX )
#else
	if( size > (size_t) SSIZE_MAX )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
		 "%s: invalid size value exceeds maximum.",
		 function );

		return( -1 );
	}
	if( size > 0 )
	{
		method_name = PyString_FromString(
			       "write" );

		argument_string = PyString_FromStringAndSize(
		                   (char *) buffer,
		                   size );

		PyErr_Clear();

		method_result = PyObject_CallMethodObjArgs(
				 file_object,
				 method_name,
				 argument_string,
				 NULL );

		if( PyErr_Occurred() )
		{
			PyErr_Fetch(
			 &exception_type,
			 &exception_value,
			 &exception_traceback );

			exception_string = PyObject_Repr(
					    exception_value );

			error_string = PyString_AsString(
					exception_string );

			if( error_string != NULL )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_WRITE_FAILED,
				 "%s: unable to write from file object with error: %s.",
				 function,
				 error_string );
			}
			else
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_IO,
				 LIBCERROR_IO_ERROR_WRITE_FAILED,
				 "%s: unable to write from file object.",
				 function );
			}
			Py_DecRef(
			 exception_string );

			goto on_error;
		}
		Py_DecRef(
		 method_result );

		Py_DecRef(
		 argument_string );

		Py_DecRef(
		 method_name );
	}
	return( (ssize_t) size );

on_error:
	if( method_result != NULL )
	{
		Py_DecRef(
		 method_result );
	}
	if( argument_string != NULL )
	{
		Py_DecRef(
		 argument_string );
	}
	if( method_name != NULL )
	{
		Py_DecRef(
		 method_name );
	}
	return( -1 );
}
void
PyErr_PrintEx(int set_sys_last_vars)
{
    PyObject *exception, *v, *tb, *hook;

    if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
        handle_system_exit();
    }
    PyErr_Fetch(&exception, &v, &tb);
    if (exception == NULL)
        return;
    PyErr_NormalizeException(&exception, &v, &tb);
    if (tb == NULL) {
        tb = Py_None;
        Py_INCREF(tb);
    }
    PyException_SetTraceback(v, tb);
    if (exception == NULL)
        return;
    /* Now we know v != NULL too */
    if (set_sys_last_vars) {
        _PySys_SetObjectId(&PyId_last_type, exception);
        _PySys_SetObjectId(&PyId_last_value, v);
        _PySys_SetObjectId(&PyId_last_traceback, tb);
    }
    hook = _PySys_GetObjectId(&PyId_excepthook);
    if (hook) {
        PyObject *args = PyTuple_Pack(3, exception, v, tb);
        PyObject *result = PyEval_CallObject(hook, args);
        if (result == NULL) {
            PyObject *exception2, *v2, *tb2;
            if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
                handle_system_exit();
            }
            PyErr_Fetch(&exception2, &v2, &tb2);
            PyErr_NormalizeException(&exception2, &v2, &tb2);
            /* It should not be possible for exception2 or v2
               to be NULL. However PyErr_Display() can't
               tolerate NULLs, so just be safe. */
            if (exception2 == NULL) {
                exception2 = Py_None;
                Py_INCREF(exception2);
            }
            if (v2 == NULL) {
                v2 = Py_None;
                Py_INCREF(v2);
            }
            fflush(stdout);
            PySys_WriteStderr("Error in sys.excepthook:\n");
            PyErr_Display(exception2, v2, tb2);
            PySys_WriteStderr("\nOriginal exception was:\n");
            PyErr_Display(exception, v, tb);
            Py_DECREF(exception2);
            Py_DECREF(v2);
            Py_XDECREF(tb2);
        }
        Py_XDECREF(result);
        Py_XDECREF(args);
    } else {
        PySys_WriteStderr("sys.excepthook is missing\n");
        PyErr_Display(exception, v, tb);
    }
    Py_XDECREF(exception);
    Py_XDECREF(v);
    Py_XDECREF(tb);
}
示例#25
0
/*
 * Get the next element from the iterator.
 *
 * The expat event handlers above (startElement, endElement, characterData) add
 * elements to the queue, which are then dequeued by this method.
 *
 * Care must be taken to store and later raise exceptions.  Any
 * exceptions raised in the expat callbacks must be stored and then
 * later thrown once the queue is emptied, otherwise the exception is
 * raised "too early" in queue order.
 */
static PyObject *
IterParser_next(IterParser* self)
{
    PyObject*  data = NULL;
    XML_Char*  buf;
    Py_ssize_t buflen;

    /* Is there anything in the queue to return? */
    if (self->queue_read_idx < self->queue_write_idx) {
        return self->queue[self->queue_read_idx++];
    }

    /* Now that the queue is empty, is there an error we need to raise? */
    if (self->error_type) {
        PyErr_Restore(self->error_type, self->error_value, self->error_traceback);
        self->error_type = NULL;
        self->error_value = NULL;
        self->error_traceback = NULL;
        return NULL;
    }

    /* The queue is empty -- have we already fed the entire file to
       expat?  If so, we are done and indicate the end of the iterator
       by simply returning NULL. */
    if (self->done) {
        return NULL;
    }

    self->queue_read_idx = 0;
    self->queue_write_idx = 0;

    do {
        /* Handle a generic Python read method */
        if (self->read) {
            data = PyObject_CallObject(self->read, self->read_args);
            if (data == NULL) {
                goto fail;
            }

            if (PyBytes_AsStringAndSize(data, &buf, &buflen) == -1) {
                Py_DECREF(data);
                goto fail;
            }

            if (buflen < self->buffersize) {
                /* EOF detection method only works for local regular files */
                self->done = 1;
            }
        /* Handle a real C file descriptor or handle -- this is faster
           if we've got one. */
        } else {
            buflen = (Py_ssize_t)read(
                self->file, self->buffer, (size_t)self->buffersize);
            if (buflen == -1) {
                PyErr_SetFromErrno(PyExc_OSError);
                goto fail;
            } else if (buflen < self->buffersize) {
                /* EOF detection method only works for local regular files */
                self->done = 1;
            }

            buf = self->buffer;
        }

        if(queue_realloc(self, buflen)) {
            Py_XDECREF(data);
            goto fail;
        }

        /* Feed the read buffer to expat, which will call the event handlers */
        if (XML_Parse(self->parser, buf, (int)buflen, self->done) == XML_STATUS_ERROR) {
            /* One of the event handlers raised a Python error, make
               note of it -- it won't be thrown until the queue is
               emptied. */
            if (PyErr_Occurred() != NULL) {
                goto fail;
            }

            /* expat raised an error, make note of it -- it won't be thrown
               until the queue is emptied. */
            Py_XDECREF(data);
            PyErr_Format(
                PyExc_ValueError, "%lu:%lu: %s",
                XML_GetCurrentLineNumber(self->parser),
                XML_GetCurrentColumnNumber(self->parser),
                XML_ErrorString(XML_GetErrorCode(self->parser)));
            goto fail;
        }
        Py_XDECREF(data);

        if (PyErr_Occurred() != NULL) {
            goto fail;
        }
    } while (self->queue_write_idx == 0 && self->done == 0);

    if (self->queue_write_idx == 0) {
        return NULL;
    }

    if (self->queue_write_idx >= self->queue_size) {
        PyErr_SetString(
            PyExc_RuntimeError,
            "XML queue overflow.  This most likely indicates an internal bug.");
        return NULL;
    }

    return self->queue[self->queue_read_idx++];

 fail:
    /* We got an exception somewhere along the way.  Store the exception in
       the IterParser object, but clear the exception in the Python interpreter,
       so we can empty the event queue and raise the exception later. */
    PyErr_Fetch(&self->error_type, &self->error_value, &self->error_traceback);
    PyErr_Clear();

    if (self->queue_read_idx < self->queue_write_idx) {
        return self->queue[self->queue_read_idx++];
    }

    PyErr_Restore(self->error_type, self->error_value, self->error_traceback);
    self->error_type = NULL;
    self->error_value = NULL;
    self->error_traceback = NULL;
    return NULL;
}
示例#26
0
bool PythonEngine::runScript(const QString &script, const QString &fileName, bool useProfiler)
{
    m_isScriptRunning = true;

    PyGILState_STATE gstate = PyGILState_Ensure();

    emit startedScript();

    bool successfulRun = false;

#pragma omp critical
    {
        QSettings settings;
        // enable user module deleter
        if (settings.value("PythonEngine/UserModuleDeleter", true).toBool())
            deleteUserModules();

        runPythonHeader();

        PyObject *output = NULL;
        if (QFile::exists(fileName))
        {
            QString str = QString("from os import chdir; chdir(u'" + QFileInfo(fileName).absolutePath() + "')");
            PyObject *import = PyRun_String(str.toLatin1().data(), Py_single_input, m_dict, m_dict);
            Py_XDECREF(import);
        }

        // compile
        PyObject *code = Py_CompileString(script.toLatin1().data(), fileName.toLatin1().data(), Py_file_input);
        // run
        if (useProfiler)
        {
            setProfilerFileName(fileName);
            startProfiler();
        }
        if (code) output = PyEval_EvalCode((PyCodeObject *) code, m_dict, m_dict);
        if (useProfiler)
            finishProfiler();

        if (output)
        {
            successfulRun = true;
            Py_XDECREF(output);
        }
        else
        {
            // error traceback
            Py_XDECREF(errorType);
            Py_XDECREF(errorValue);
            Py_XDECREF(errorTraceback);
            PyErr_Fetch(&errorType, &errorValue, &errorTraceback);
            if (errorTraceback)
                successfulRun = false;
        }

        Py_XDECREF(code);

        m_isScriptRunning = false;
    }

    // release the thread, no Python API allowed beyond this point
    PyGILState_Release(gstate);

    emit executedScript();

    return successfulRun;
}
示例#27
0
static int green_updatecurrent(void)
{
	PyObject *exc, *val, *tb;
	PyThreadState* tstate;
	PyGreenlet* current;
	PyGreenlet* previous;
	PyObject* deleteme;

green_updatecurrent_restart:
	/* save current exception */
	PyErr_Fetch(&exc, &val, &tb);

	/* get ts_current from the active tstate */
	tstate = PyThreadState_GET();
	if (tstate->dict && (current =
	    (PyGreenlet*) PyDict_GetItem(tstate->dict, ts_curkey))) {
		/* found -- remove it, to avoid keeping a ref */
		Py_INCREF(current);
		PyDict_DelItem(tstate->dict, ts_curkey);
	}
	else {
		/* first time we see this tstate */
		current = green_create_main();
		if (current == NULL) {
			Py_XDECREF(exc);
			Py_XDECREF(val);
			Py_XDECREF(tb);
			return -1;
		}
	}
	assert(current->run_info == tstate->dict);

green_updatecurrent_retry:
	/* update ts_current as soon as possible, in case of nested switches */
	Py_INCREF(current);
	previous = ts_current;
	ts_current = current;

	/* save ts_current as the current greenlet of its own thread */
	if (PyDict_SetItem(previous->run_info, ts_curkey, (PyObject*) previous)) {
		Py_DECREF(previous);
		Py_DECREF(current);
		Py_XDECREF(exc);
		Py_XDECREF(val);
		Py_XDECREF(tb);
		return -1;
	}
	Py_DECREF(previous);

	/* green_dealloc() cannot delete greenlets from other threads, so
	   it stores them in the thread dict; delete them now. */
	deleteme = PyDict_GetItem(tstate->dict, ts_delkey);
	if (deleteme != NULL) {
		PyList_SetSlice(deleteme, 0, INT_MAX, NULL);
	}

	if (ts_current != current) {
		/* some Python code executed above and there was a thread switch,
		 * so ts_current points to some other thread again. We need to
		 * delete ts_curkey (it's likely there) and retry. */
		PyDict_DelItem(tstate->dict, ts_curkey);
		goto green_updatecurrent_retry;
	}

	/* release an extra reference */
	Py_DECREF(current);

	/* restore current exception */
	PyErr_Restore(exc, val, tb);

	/* thread switch could happen during PyErr_Restore, in that
	   case there's nothing to do except restart from scratch. */
	if (ts_current->run_info != tstate->dict)
		goto green_updatecurrent_restart;

	return 0;
}
示例#28
0
bool PythonEngine::runExpression(const QString &expression, double *value, const QString &command)
{
    while (m_isExpressionRunning)
    {
        qDebug() << "Expression is running" << expression;
        msleep(10);
    }

    bool successfulRun = false;

    m_isExpressionRunning = true;

    PyObject *output = NULL;

    runPythonHeader();

    if (value)
    {
        // return value
        QString exp;
        if (command.isEmpty())
            exp = QString("result_pythonlab = %1").arg(expression);
        else
            exp = QString("%1; result_pythonlab = %2").arg(command).arg(expression);

        output = PyRun_String(exp.toLatin1().data(), Py_single_input, m_dict, m_dict);

        if (output)
        {
            // parse result
            PyObject *result = PyDict_GetItemString(m_dict, "result_pythonlab");

            if (result)
            {
                if ((QString(result->ob_type->tp_name) == "bool") ||
                        (QString(result->ob_type->tp_name) == "int") ||
                        (QString(result->ob_type->tp_name) == "float"))
                {
                    Py_INCREF(result);
                    PyArg_Parse(result, "d", value);
                    if (fabs(*value) < EPS_ZERO)
                        *value = 0.0;
                    Py_XDECREF(result);

                    successfulRun = true;
                }
                else
                {
                    qDebug() << tr("Type '%1' is not supported.").arg(result->ob_type->tp_name).arg(expression);

                    successfulRun = false;
                }
            }

            // speed up?
            // PyRun_String("del result_pythonlab", Py_single_input, m_dict, m_dict);
        }

    }
    else
    {
        output = PyRun_String(expression.toLatin1().data(), Py_single_input, m_dict, m_dict);
        if (output)
            successfulRun = true;
    }

    if (!output)
    {
        // error traceback
        Py_XDECREF(errorType);
        Py_XDECREF(errorValue);
        Py_XDECREF(errorTraceback);
        PyErr_Fetch(&errorType, &errorValue, &errorTraceback);
        if (errorTraceback)
            successfulRun = false;
    }

    Py_XDECREF(output);

    m_isExpressionRunning = false;

    return successfulRun;
}
示例#29
0
static void green_dealloc_safe(PyGreenlet* self)
{
	PyObject *error_type, *error_value, *error_traceback;

	if (PyGreenlet_ACTIVE(self) && self->run_info != NULL && !PyGreenlet_MAIN(self)) {
		/* Hacks hacks hacks copied from instance_dealloc() */
		/* Temporarily resurrect the greenlet. */
		assert(Py_REFCNT(self) == 0);
		Py_REFCNT(self) = 1;
		/* Save the current exception, if any. */
		PyErr_Fetch(&error_type, &error_value, &error_traceback);
		if (kill_greenlet(self) < 0) {
			PyErr_WriteUnraisable((PyObject*) self);
			/* XXX what else should we do? */
		}
		/* Check for no resurrection must be done while we keep
		 * our internal reference, otherwise PyFile_WriteObject
		 * causes recursion if using Py_INCREF/Py_DECREF
		 */
		if (Py_REFCNT(self) == 1 && PyGreenlet_ACTIVE(self)) {
			/* Not resurrected, but still not dead!
			   XXX what else should we do? we complain. */
			PyObject* f = PySys_GetObject("stderr");
			Py_INCREF(self); /* leak! */
			if (f != NULL) {
				PyFile_WriteString("GreenletExit did not kill ",
				                   f);
				PyFile_WriteObject((PyObject*) self, f, 0);
				PyFile_WriteString("\n", f);
			}
		}
		/* Restore the saved exception. */
		PyErr_Restore(error_type, error_value, error_traceback);
		/* Undo the temporary resurrection; can't use DECREF here,
		 * it would cause a recursive call.
		 */
		assert(Py_REFCNT(self) > 0);
		if (--Py_REFCNT(self) != 0) {
			/* Resurrected! */
			Py_ssize_t refcnt = Py_REFCNT(self);
			_Py_NewReference((PyObject*) self);
			Py_REFCNT(self) = refcnt;
#if GREENLET_USE_GC
			PyObject_GC_Track((PyObject *)self);
#endif
			_Py_DEC_REFTOTAL;
#ifdef COUNT_ALLOCS
			--Py_TYPE(self)->tp_frees;
			--Py_TYPE(self)->tp_allocs;
#endif /* COUNT_ALLOCS */
			return;
		}
	}
	if (self->weakreflist != NULL)
		PyObject_ClearWeakRefs((PyObject *) self);
	Py_CLEAR(self->parent);
	Py_CLEAR(self->run_info);
	Py_CLEAR(self->exc_type);
	Py_CLEAR(self->exc_value);
	Py_CLEAR(self->exc_traceback);
	Py_CLEAR(self->dict);
	Py_TYPE(self)->tp_free((PyObject*) self);
}
示例#30
0
/*
 * Emit a PG error or notice, together with any available info about
 * the current Python error, previously set by PLy_exception_set().
 * This should be used to propagate Python errors into PG.	If fmt is
 * NULL, the Python error becomes the primary error message, otherwise
 * it becomes the detail.  If there is a Python traceback, it is put
 * in the context.
 */
void
PLy_elog(int elevel, const char *fmt,...)
{
	char	   *xmsg;
	char	   *tbmsg;
	int			tb_depth;
	StringInfoData emsg;
	PyObject   *exc,
			   *val,
			   *tb;
	const char *primary = NULL;
	int		   sqlerrcode = 0;
	char	   *detail = NULL;
	char	   *hint = NULL;
	char	   *query = NULL;
	int			position = 0;

	PyErr_Fetch(&exc, &val, &tb);
	if (exc != NULL)
	{
		if (PyErr_GivenExceptionMatches(val, PLy_exc_spi_error))
			PLy_get_spi_error_data(val, &sqlerrcode, &detail, &hint, &query, &position);
		else if (PyErr_GivenExceptionMatches(val, PLy_exc_fatal))
			elevel = FATAL;
	}
	PyErr_Restore(exc, val, tb);

	PLy_traceback(&xmsg, &tbmsg, &tb_depth);

	if (fmt)
	{
		initStringInfo(&emsg);
		for (;;)
		{
			va_list		ap;
			bool		success;

			va_start(ap, fmt);
			success = appendStringInfoVA(&emsg, dgettext(TEXTDOMAIN, fmt), ap);
			va_end(ap);
			if (success)
				break;
			enlargeStringInfo(&emsg, emsg.maxlen);
		}
		primary = emsg.data;

		/* Since we have a format string, we cannot have a SPI detail. */
		Assert(detail == NULL);

		/* If there's an exception message, it goes in the detail. */
		if (xmsg)
			detail = xmsg;
	}
	else
	{
		if (xmsg)
			primary = xmsg;
	}

	PG_TRY();
	{
		ereport(elevel,
				(errcode(sqlerrcode ? sqlerrcode : ERRCODE_INTERNAL_ERROR),
				 errmsg_internal("%s", primary ? primary : "no exception data"),
				 (detail) ? errdetail_internal("%s", detail) : 0,
				 (tb_depth > 0 && tbmsg) ? errcontext("%s", tbmsg) : 0,
				 (hint) ? errhint("%s", hint) : 0,
				 (query) ? internalerrquery(query) : 0,
				 (position) ? internalerrposition(position) : 0));
	}
	PG_CATCH();
	{
		if (fmt)
			pfree(emsg.data);
		if (xmsg)
			pfree(xmsg);
		if (tbmsg)
			pfree(tbmsg);
		PG_RE_THROW();
	}
	PG_END_TRY();

	if (fmt)
		pfree(emsg.data);
	if (xmsg)
		pfree(xmsg);
	if (tbmsg)
		pfree(tbmsg);
}