py-function.c revision 1.3
1/* Convenience functions implemented in Python. 2 3 Copyright (C) 2008-2015 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 21#include "defs.h" 22#include "value.h" 23#include "python-internal.h" 24#include "charset.h" 25#include "gdbcmd.h" 26#include "cli/cli-decode.h" 27#include "completer.h" 28#include "expression.h" 29#include "language.h" 30 31static PyTypeObject fnpy_object_type 32 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("PyObject"); 33 34 35 36static PyObject * 37convert_values_to_python (int argc, struct value **argv) 38{ 39 int i; 40 PyObject *result = PyTuple_New (argc); 41 42 if (! result) 43 return NULL; 44 45 for (i = 0; i < argc; ++i) 46 { 47 PyObject *elt = value_to_value_object (argv[i]); 48 if (! elt) 49 { 50 Py_DECREF (result); 51 return NULL; 52 } 53 PyTuple_SetItem (result, i, elt); 54 } 55 return result; 56} 57 58/* Call a Python function object's invoke method. */ 59 60static struct value * 61fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, 62 void *cookie, int argc, struct value **argv) 63{ 64 struct value *value = NULL; 65 /* 'result' must be set to NULL, this initially indicates whether 66 the function was called, or not. */ 67 PyObject *result = NULL; 68 PyObject *callable, *args; 69 struct cleanup *cleanup; 70 71 cleanup = ensure_python_env (gdbarch, language); 72 73 args = convert_values_to_python (argc, argv); 74 /* convert_values_to_python can return NULL on error. If we 75 encounter this, do not call the function, but allow the Python -> 76 error code conversion below to deal with the Python exception. 77 Note, that this is different if the function simply does not 78 have arguments. */ 79 80 if (args) 81 { 82 callable = PyObject_GetAttrString ((PyObject *) cookie, "invoke"); 83 if (! callable) 84 { 85 Py_DECREF (args); 86 error (_("No method named 'invoke' in object.")); 87 } 88 89 result = PyObject_Call (callable, args, NULL); 90 Py_DECREF (callable); 91 Py_DECREF (args); 92 } 93 94 if (!result) 95 { 96 PyObject *ptype, *pvalue, *ptraceback; 97 char *msg; 98 99 PyErr_Fetch (&ptype, &pvalue, &ptraceback); 100 101 /* Try to fetch an error message contained within ptype, pvalue. 102 When fetching the error message we need to make our own copy, 103 we no longer own ptype, pvalue after the call to PyErr_Restore. */ 104 105 msg = gdbpy_exception_to_string (ptype, pvalue); 106 make_cleanup (xfree, msg); 107 108 if (msg == NULL) 109 { 110 /* An error occurred computing the string representation of the 111 error message. This is rare, but we should inform the user. */ 112 113 printf_filtered (_("An error occurred in a Python " 114 "convenience function\n" 115 "and then another occurred computing the " 116 "error message.\n")); 117 gdbpy_print_stack (); 118 } 119 120 /* Don't print the stack for gdb.GdbError exceptions. 121 It is generally used to flag user errors. 122 123 We also don't want to print "Error occurred in Python command" 124 for user errors. However, a missing message for gdb.GdbError 125 exceptions is arguably a bug, so we flag it as such. */ 126 127 if (!PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc) 128 || msg == NULL || *msg == '\0') 129 { 130 PyErr_Restore (ptype, pvalue, ptraceback); 131 gdbpy_print_stack (); 132 if (msg != NULL && *msg != '\0') 133 error (_("Error occurred in Python convenience function: %s"), 134 msg); 135 else 136 error (_("Error occurred in Python convenience function.")); 137 } 138 else 139 { 140 Py_XDECREF (ptype); 141 Py_XDECREF (pvalue); 142 Py_XDECREF (ptraceback); 143 error ("%s", msg); 144 } 145 } 146 147 value = convert_value_from_python (result); 148 if (value == NULL) 149 { 150 Py_DECREF (result); 151 gdbpy_print_stack (); 152 error (_("Error while executing Python code.")); 153 } 154 155 Py_DECREF (result); 156 do_cleanups (cleanup); 157 158 return value; 159} 160 161/* Initializer for a Function object. It takes one argument, the name 162 of the function. */ 163 164static int 165fnpy_init (PyObject *self, PyObject *args, PyObject *kwds) 166{ 167 const char *name; 168 char *docstring = NULL; 169 170 if (! PyArg_ParseTuple (args, "s", &name)) 171 return -1; 172 Py_INCREF (self); 173 174 if (PyObject_HasAttrString (self, "__doc__")) 175 { 176 PyObject *ds_obj = PyObject_GetAttrString (self, "__doc__"); 177 if (ds_obj != NULL) 178 { 179 if (gdbpy_is_string (ds_obj)) 180 { 181 docstring = python_string_to_host_string (ds_obj); 182 if (docstring == NULL) 183 { 184 Py_DECREF (self); 185 Py_DECREF (ds_obj); 186 return -1; 187 } 188 } 189 190 Py_DECREF (ds_obj); 191 } 192 } 193 if (! docstring) 194 docstring = xstrdup (_("This function is not documented.")); 195 196 add_internal_function (name, docstring, fnpy_call, self); 197 return 0; 198} 199 200/* Initialize internal function support. */ 201 202int 203gdbpy_initialize_functions (void) 204{ 205 fnpy_object_type.tp_new = PyType_GenericNew; 206 if (PyType_Ready (&fnpy_object_type) < 0) 207 return -1; 208 209 return gdb_pymodule_addobject (gdb_module, "Function", 210 (PyObject *) &fnpy_object_type); 211} 212 213 214 215static PyTypeObject fnpy_object_type = 216{ 217 PyVarObject_HEAD_INIT (NULL, 0) 218 "gdb.Function", /*tp_name*/ 219 sizeof (PyObject), /*tp_basicsize*/ 220 0, /*tp_itemsize*/ 221 0, /*tp_dealloc*/ 222 0, /*tp_print*/ 223 0, /*tp_getattr*/ 224 0, /*tp_setattr*/ 225 0, /*tp_compare*/ 226 0, /*tp_repr*/ 227 0, /*tp_as_number*/ 228 0, /*tp_as_sequence*/ 229 0, /*tp_as_mapping*/ 230 0, /*tp_hash */ 231 0, /*tp_call*/ 232 0, /*tp_str*/ 233 0, /*tp_getattro*/ 234 0, /*tp_setattro*/ 235 0, /*tp_as_buffer*/ 236 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 237 "GDB function object", /* tp_doc */ 238 0, /* tp_traverse */ 239 0, /* tp_clear */ 240 0, /* tp_richcompare */ 241 0, /* tp_weaklistoffset */ 242 0, /* tp_iter */ 243 0, /* tp_iternext */ 244 0, /* tp_methods */ 245 0, /* tp_members */ 246 0, /* tp_getset */ 247 0, /* tp_base */ 248 0, /* tp_dict */ 249 0, /* tp_descr_get */ 250 0, /* tp_descr_set */ 251 0, /* tp_dictoffset */ 252 fnpy_init, /* tp_init */ 253 0, /* tp_alloc */ 254}; 255