/* General utility routines for GDB/Python.
- Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "charset.h"
#include "value.h"
#include "python-internal.h"
-
-
-/* This is a cleanup function which decrements the refcount on a
- Python object. */
-
-static void
-py_decref (void *p)
-{
- PyObject *py = p;
-
- /* Note that we need the extra braces in this 'if' to avoid a
- warning from gcc. */
- if (py)
- {
- Py_DECREF (py);
- }
-}
-
-/* Return a new cleanup which will decrement the Python object's
- refcount when run. */
-
-struct cleanup *
-make_cleanup_py_decref (PyObject *py)
-{
- return make_cleanup (py_decref, (void *) py);
-}
+#include "py-ref.h"
/* Converts a Python 8-bit string to a unicode string object. Assumes the
8-bit string is in the host charset. If an error occurs during conversion,
As an added bonus, the functions accepts a unicode string and returns it
right away, so callers don't need to check which kind of string they've
- got.
+ got. In Python 3, all strings are Unicode so this case is always the
+ one that applies.
If the given object is not one of the mentioned string types, NULL is
returned, with the TypeError python exception set. */
unicode_str = obj;
Py_INCREF (obj);
}
-
+#ifndef IS_PY3K
else if (PyString_Check (obj))
unicode_str = PyUnicode_FromEncodedObject (obj, host_charset (), NULL);
+#endif
else
{
PyErr_SetString (PyExc_TypeError,
conversion, NULL will be returned and a python exception will be set.
The caller is responsible for xfree'ing the string. */
-static char *
+static gdb::unique_xmalloc_ptr<char>
unicode_to_encoded_string (PyObject *unicode_str, const char *charset)
{
- char *result;
- PyObject *string;
+ gdb::unique_xmalloc_ptr<char> result;
/* Translate string to named charset. */
- string = PyUnicode_AsEncodedString (unicode_str, charset, NULL);
+ gdbpy_ref<> string (PyUnicode_AsEncodedString (unicode_str, charset, NULL));
if (string == NULL)
return NULL;
- result = xstrdup (PyString_AsString (string));
-
- Py_DECREF (string);
+#ifdef IS_PY3K
+ result.reset (xstrdup (PyBytes_AsString (string.get ())));
+#else
+ result.reset (xstrdup (PyString_AsString (string.get ())));
+#endif
return result;
}
static PyObject *
unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset)
{
- PyObject *string;
-
/* Translate string to named charset. */
- string = PyUnicode_AsEncodedString (unicode_str, charset, NULL);
- if (string == NULL)
- return NULL;
-
- return string;
+ return PyUnicode_AsEncodedString (unicode_str, charset, NULL);
}
-/* Returns a newly allocated string with the contents of the given unicode
- string object converted to the target's charset. If an error occurs during
- the conversion, NULL will be returned and a python exception will be set.
-
- The caller is responsible for xfree'ing the string. */
-char *
+/* Returns a newly allocated string with the contents of the given
+ unicode string object converted to the target's charset. If an
+ error occurs during the conversion, NULL will be returned and a
+ python exception will be set. */
+gdb::unique_xmalloc_ptr<char>
unicode_to_target_string (PyObject *unicode_str)
{
return unicode_to_encoded_string (unicode_str,
object converted to the target's charset. If an error occurs
during the conversion, NULL will be returned and a python exception
will be set. */
-PyObject *
+static PyObject *
unicode_to_target_python_string (PyObject *unicode_str)
{
return unicode_to_encoded_python_string (unicode_str,
}
/* Converts a python string (8-bit or unicode) to a target string in
- the target's charset. Returns NULL on error, with a python exception set.
-
- The caller is responsible for xfree'ing the string. */
-char *
+ the target's charset. Returns NULL on error, with a python
+ exception set. */
+gdb::unique_xmalloc_ptr<char>
python_string_to_target_string (PyObject *obj)
{
- PyObject *str;
- char *result;
-
- str = python_string_to_unicode (obj);
+ gdbpy_ref<> str (python_string_to_unicode (obj));
if (str == NULL)
return NULL;
- result = unicode_to_target_string (str);
- Py_DECREF (str);
- return result;
+ return unicode_to_target_string (str.get ());
}
/* Converts a python string (8-bit or unicode) to a target string in the
target's charset. Returns NULL on error, with a python exception
- set. */
+ set.
+
+ In Python 3, the returned object is a "bytes" object (not a string). */
PyObject *
python_string_to_target_python_string (PyObject *obj)
{
- PyObject *str;
- PyObject *result;
-
- str = python_string_to_unicode (obj);
+ gdbpy_ref<> str (python_string_to_unicode (obj));
if (str == NULL)
return NULL;
- result = unicode_to_target_python_string (str);
- Py_DECREF (str);
- return result;
+ return unicode_to_target_python_string (str.get ());
}
/* Converts a python string (8-bit or unicode) to a target string in
- the host's charset. Returns NULL on error, with a python exception set.
-
- The caller is responsible for xfree'ing the string. */
-char *
+ the host's charset. Returns NULL on error, with a python exception
+ set. */
+gdb::unique_xmalloc_ptr<char>
python_string_to_host_string (PyObject *obj)
{
- PyObject *str;
- char *result;
-
- str = python_string_to_unicode (obj);
+ gdbpy_ref<> str (python_string_to_unicode (obj));
if (str == NULL)
return NULL;
- result = unicode_to_encoded_string (str, host_charset ());
- Py_DECREF (str);
- return result;
+ return unicode_to_encoded_string (str.get (), host_charset ());
}
-/* Converts a target string of LENGTH bytes in the target's charset to a
- Python Unicode string. If LENGTH is -1, convert until a null byte is found.
+/* Convert a host string to a python string. */
- Returns NULL on error, with a python exception set. */
PyObject *
-target_string_to_unicode (const gdb_byte *str, int length)
+host_string_to_python_string (const char *str)
{
- if (length == -1)
- length = strlen (str);
-
- return PyUnicode_Decode (str, length, target_charset (python_gdbarch), NULL);
+ return PyString_Decode (str, strlen (str), host_charset (), NULL);
}
/* Return true if OBJ is a Python string or unicode object, false
int
gdbpy_is_string (PyObject *obj)
{
+#ifdef IS_PY3K
+ return PyUnicode_Check (obj);
+#else
return PyString_Check (obj) || PyUnicode_Check (obj);
+#endif
}
/* Return the string representation of OBJ, i.e., str (obj).
- Space for the result is malloc'd, the caller must free.
If the result is NULL a python error occurred, the caller must clear it. */
-char *
+gdb::unique_xmalloc_ptr<char>
gdbpy_obj_to_string (PyObject *obj)
{
- PyObject *str_obj = PyObject_Str (obj);
+ gdbpy_ref<> str_obj (PyObject_Str (obj));
if (str_obj != NULL)
{
- char *msg = xstrdup (PyString_AsString (str_obj));
+ gdb::unique_xmalloc_ptr<char> msg;
+
+#ifdef IS_PY3K
+ msg = python_string_to_host_string (str_obj.get ());
+#else
+ msg.reset (xstrdup (PyString_AsString (str_obj.get ())));
+#endif
- Py_DECREF (str_obj);
return msg;
}
/* Return the string representation of the exception represented by
TYPE, VALUE which is assumed to have been obtained with PyErr_Fetch,
i.e., the error indicator is currently clear.
- Space for the result is malloc'd, the caller must free.
If the result is NULL a python error occurred, the caller must clear it. */
-char *
+gdb::unique_xmalloc_ptr<char>
gdbpy_exception_to_string (PyObject *ptype, PyObject *pvalue)
{
- PyObject *str_obj = PyObject_Str (pvalue);
- char *str;
-
/* There are a few cases to consider.
For example:
pvalue is a string when PyErr_SetString is used.
gdb.GdbError ("message"). */
if (pvalue && pvalue != Py_None)
- str = gdbpy_obj_to_string (pvalue);
+ return gdbpy_obj_to_string (pvalue);
+ else
+ return gdbpy_obj_to_string (ptype);
+}
+
+/* Convert a GDB exception to the appropriate Python exception.
+
+ This sets the Python error indicator. */
+
+void
+gdbpy_convert_exception (struct gdb_exception exception)
+{
+ PyObject *exc_class;
+
+ if (exception.reason == RETURN_QUIT)
+ exc_class = PyExc_KeyboardInterrupt;
+ else if (exception.error == MEMORY_ERROR)
+ exc_class = gdbpy_gdb_memory_error;
else
- str = gdbpy_obj_to_string (ptype);
+ exc_class = gdbpy_gdb_error;
- return str;
+ PyErr_Format (exc_class, "%s", exception.message);
}
/* Converts OBJ to a CORE_ADDR value.
- Returns 1 on success or 0 on failure, with a Python exception set. This
- function can also throw GDB exceptions.
+ Returns 0 on success or -1 on failure, with a Python exception set.
*/
int
get_addr_from_python (PyObject *obj, CORE_ADDR *addr)
{
if (gdbpy_is_value_object (obj))
- *addr = value_as_address (value_object_to_value (obj));
- else if (PyLong_Check (obj))
{
- /* Assume CORE_ADDR corresponds to unsigned long. */
- *addr = PyLong_AsUnsignedLong (obj);
- if (PyErr_Occurred () != NULL)
- return 0;
+
+ TRY
+ {
+ *addr = value_as_address (value_object_to_value (obj));
+ }
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_SET_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
+ }
+ else
+ {
+ gdbpy_ref<> num (PyNumber_Long (obj));
+ gdb_py_ulongest val;
+
+ if (num == NULL)
+ return -1;
+
+ val = gdb_py_long_as_ulongest (num.get ());
+ if (PyErr_Occurred ())
+ return -1;
+
+ if (sizeof (val) > sizeof (CORE_ADDR) && ((CORE_ADDR) val) != val)
+ {
+ PyErr_SetString (PyExc_ValueError,
+ _("Overflow converting to address."));
+ return -1;
+ }
+
+ *addr = val;
}
- else if (PyInt_Check (obj))
+
+ return 0;
+}
+
+/* Convert a LONGEST to the appropriate Python object -- either an
+ integer object or a long object, depending on its value. */
+
+PyObject *
+gdb_py_object_from_longest (LONGEST l)
+{
+#ifdef IS_PY3K
+ if (sizeof (l) > sizeof (long))
+ return PyLong_FromLongLong (l);
+ return PyLong_FromLong (l);
+#else
+#ifdef HAVE_LONG_LONG /* Defined by Python. */
+ /* If we have 'long long', and the value overflows a 'long', use a
+ Python Long; otherwise use a Python Int. */
+ if (sizeof (l) > sizeof (long)
+ && (l > PyInt_GetMax () || l < (- (LONGEST) PyInt_GetMax ()) - 1))
+ return PyLong_FromLongLong (l);
+#endif
+ return PyInt_FromLong (l);
+#endif
+}
+
+/* Convert a ULONGEST to the appropriate Python object -- either an
+ integer object or a long object, depending on its value. */
+
+PyObject *
+gdb_py_object_from_ulongest (ULONGEST l)
+{
+#ifdef IS_PY3K
+ if (sizeof (l) > sizeof (unsigned long))
+ return PyLong_FromUnsignedLongLong (l);
+ return PyLong_FromUnsignedLong (l);
+#else
+#ifdef HAVE_LONG_LONG /* Defined by Python. */
+ /* If we have 'long long', and the value overflows a 'long', use a
+ Python Long; otherwise use a Python Int. */
+ if (sizeof (l) > sizeof (unsigned long) && l > PyInt_GetMax ())
+ return PyLong_FromUnsignedLongLong (l);
+#endif
+
+ if (l > PyInt_GetMax ())
+ return PyLong_FromUnsignedLong (l);
+
+ return PyInt_FromLong (l);
+#endif
+}
+
+/* Like PyInt_AsLong, but returns 0 on failure, 1 on success, and puts
+ the value into an out parameter. */
+
+int
+gdb_py_int_as_long (PyObject *obj, long *result)
+{
+ *result = PyInt_AsLong (obj);
+ return ! (*result == -1 && PyErr_Occurred ());
+}
+
+\f
+
+/* Generic implementation of the __dict__ attribute for objects that
+ have a dictionary. The CLOSURE argument should be the type object.
+ This only handles positive values for tp_dictoffset. */
+
+PyObject *
+gdb_py_generic_dict (PyObject *self, void *closure)
+{
+ PyObject *result;
+ PyTypeObject *type_obj = (PyTypeObject *) closure;
+ char *raw_ptr;
+
+ raw_ptr = (char *) self + type_obj->tp_dictoffset;
+ result = * (PyObject **) raw_ptr;
+
+ Py_INCREF (result);
+ return result;
+}
+
+/* Like PyModule_AddObject, but does not steal a reference to
+ OBJECT. */
+
+int
+gdb_pymodule_addobject (PyObject *module, const char *name, PyObject *object)
+{
+ int result;
+
+ Py_INCREF (object);
+ /* Python 2.4 did not have a 'const' here. */
+ result = PyModule_AddObject (module, (char *) name, object);
+ if (result < 0)
+ Py_DECREF (object);
+ return result;
+}
+
+/* Handle a Python exception when the special gdb.GdbError treatment
+ is desired. This should only be called when an exception is set.
+ If the exception is a gdb.GdbError, throw a gdb exception with the
+ exception text. For other exceptions, print the Python stack and
+ then throw a gdb exception. */
+
+void
+gdbpy_handle_exception ()
+{
+ PyObject *ptype, *pvalue, *ptraceback;
+
+ PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+
+ /* Try to fetch an error message contained within ptype, pvalue.
+ When fetching the error message we need to make our own copy,
+ we no longer own ptype, pvalue after the call to PyErr_Restore. */
+
+ gdb::unique_xmalloc_ptr<char>
+ msg (gdbpy_exception_to_string (ptype, pvalue));
+
+ if (msg == NULL)
{
- long val;
+ /* An error occurred computing the string representation of the
+ error message. This is rare, but we should inform the user. */
+ printf_filtered (_("An error occurred in Python "
+ "and then another occurred computing the "
+ "error message.\n"));
+ gdbpy_print_stack ();
+ }
+
+ /* Don't print the stack for gdb.GdbError exceptions.
+ It is generally used to flag user errors.
- /* Assume CORE_ADDR corresponds to unsigned long. */
- val = PyInt_AsLong (obj);
+ We also don't want to print "Error occurred in Python command"
+ for user errors. However, a missing message for gdb.GdbError
+ exceptions is arguably a bug, so we flag it as such. */
- if (val >= 0)
- *addr = val;
+ if (! PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc)
+ || msg == NULL || *msg == '\0')
+ {
+ PyErr_Restore (ptype, pvalue, ptraceback);
+ gdbpy_print_stack ();
+ if (msg != NULL && *msg != '\0')
+ error (_("Error occurred in Python: %s"), msg.get ());
else
- {
- /* If no error ocurred, VAL is indeed negative. */
- if (PyErr_Occurred () != NULL)
- return 0;
-
- PyErr_SetString (PyExc_ValueError,
- _("Supplied address is negative."));
- return 0;
- }
+ error (_("Error occurred in Python."));
}
else
{
- PyErr_SetString (PyExc_TypeError,
- _("Invalid type for address."));
- return 0;
+ Py_XDECREF (ptype);
+ Py_XDECREF (pvalue);
+ Py_XDECREF (ptraceback);
+ error ("%s", msg.get ());
}
-
- return 1;
}