1 /* Support for debug methods in Python.
3 Copyright (C) 2013-2018 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
21 #include "arch-utils.h"
22 #include "extension-priv.h"
28 #include "python-internal.h"
31 static const char enabled_field_name[] = "enabled";
32 static const char match_method_name[] = "match";
33 static const char get_arg_types_method_name[] = "get_arg_types";
34 static const char get_result_type_method_name[] = "get_result_type";
35 static const char matchers_attr_str[] = "xmethods";
37 static PyObject *py_match_method_name = NULL;
38 static PyObject *py_get_arg_types_method_name = NULL;
40 struct python_xmethod_worker : xmethod_worker
42 python_xmethod_worker (PyObject *worker, PyObject *this_type);
43 ~python_xmethod_worker ();
45 DISABLE_COPY_AND_ASSIGN (python_xmethod_worker);
47 /* Implementation of xmethod_worker::invoke for Python. */
49 value *invoke (value *obj, value **args, int nargs) override;
51 /* Implementation of xmethod_worker::do_get_arg_types for Python. */
53 ext_lang_rc do_get_arg_types (int *nargs, type ***arg_types) override;
55 /* Implementation of xmethod_worker::do_get_result_type for Python.
57 For backward compatibility with 7.9, which did not support getting the
58 result type, if the get_result_type operation is not provided by WORKER
59 then EXT_LANG_RC_OK is returned and NULL is returned in *RESULT_TYPE. */
61 ext_lang_rc do_get_result_type (value *obj, value **args, int nargs,
62 type **result_type_ptr) override;
66 PyObject *m_py_worker;
67 PyObject *m_this_type;
70 python_xmethod_worker::~python_xmethod_worker ()
72 /* We don't do much here, but we still need the GIL. */
73 gdbpy_enter enter_py (get_current_arch (), current_language);
75 Py_DECREF (m_py_worker);
76 Py_DECREF (m_this_type);
79 /* Invoke the "match" method of the MATCHER and return a new reference
80 to the result. Returns NULL on error. */
83 invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
84 const char *xmethod_name)
88 gdbpy_ref<> enabled_field (PyObject_GetAttrString (matcher,
90 if (enabled_field == NULL)
93 enabled = PyObject_IsTrue (enabled_field.get ());
98 /* Return 'None' if the matcher is not enabled. */
102 gdbpy_ref<> match_method (PyObject_GetAttrString (matcher,
104 if (match_method == NULL)
107 gdbpy_ref<> py_xmethod_name (PyString_FromString (xmethod_name));
108 if (py_xmethod_name == NULL)
111 return PyObject_CallMethodObjArgs (matcher, py_match_method_name,
112 py_obj_type, py_xmethod_name.get (),
116 /* Implementation of get_matching_xmethod_workers for Python. */
119 gdbpy_get_matching_xmethod_workers
120 (const struct extension_language_defn *extlang,
121 struct type *obj_type, const char *method_name,
122 std::vector<xmethod_worker_up> *dm_vec)
124 struct objfile *objfile;
125 PyObject *py_progspace;
127 gdb_assert (obj_type != NULL && method_name != NULL);
129 gdbpy_enter enter_py (get_current_arch (), current_language);
131 gdbpy_ref<> py_type (type_to_type_object (obj_type));
134 gdbpy_print_stack ();
135 return EXT_LANG_RC_ERROR;
138 /* Create an empty list of debug methods. */
139 gdbpy_ref<> py_xmethod_matcher_list (PyList_New (0));
140 if (py_xmethod_matcher_list == NULL)
142 gdbpy_print_stack ();
143 return EXT_LANG_RC_ERROR;
146 /* Gather debug method matchers registered with the object files.
147 This could be done differently by iterating over each objfile's matcher
148 list individually, but there's no data yet to show it's needed. */
149 ALL_OBJFILES (objfile)
151 PyObject *py_objfile = objfile_to_objfile_object (objfile);
153 if (py_objfile == NULL)
155 gdbpy_print_stack ();
156 return EXT_LANG_RC_ERROR;
159 gdbpy_ref<> objfile_matchers (objfpy_get_xmethods (py_objfile, NULL));
160 gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
161 objfile_matchers.get ()));
164 gdbpy_print_stack ();
165 return EXT_LANG_RC_ERROR;
168 py_xmethod_matcher_list = std::move (temp);
171 /* Gather debug methods matchers registered with the current program
173 py_progspace = pspace_to_pspace_object (current_program_space);
174 if (py_progspace != NULL)
176 gdbpy_ref<> pspace_matchers (pspy_get_xmethods (py_progspace, NULL));
178 gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
179 pspace_matchers.get ()));
182 gdbpy_print_stack ();
183 return EXT_LANG_RC_ERROR;
186 py_xmethod_matcher_list = std::move (temp);
190 gdbpy_print_stack ();
191 return EXT_LANG_RC_ERROR;
194 /* Gather debug method matchers registered globally. */
195 if (gdb_python_module != NULL
196 && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
198 gdbpy_ref<> gdb_matchers (PyObject_GetAttrString (gdb_python_module,
200 if (gdb_matchers != NULL)
202 gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
203 gdb_matchers.get ()));
206 gdbpy_print_stack ();
207 return EXT_LANG_RC_ERROR;
210 py_xmethod_matcher_list = std::move (temp);
214 gdbpy_print_stack ();
215 return EXT_LANG_RC_ERROR;
219 gdbpy_ref<> list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
220 if (list_iter == NULL)
222 gdbpy_print_stack ();
223 return EXT_LANG_RC_ERROR;
227 gdbpy_ref<> matcher (PyIter_Next (list_iter.get ()));
230 if (PyErr_Occurred ())
232 gdbpy_print_stack ();
233 return EXT_LANG_RC_ERROR;
238 gdbpy_ref<> match_result (invoke_match_method (matcher.get (),
242 if (match_result == NULL)
244 gdbpy_print_stack ();
245 return EXT_LANG_RC_ERROR;
247 if (match_result == Py_None)
248 ; /* This means there was no match. */
249 else if (PySequence_Check (match_result.get ()))
251 gdbpy_ref<> iter (PyObject_GetIter (match_result.get ()));
255 gdbpy_print_stack ();
256 return EXT_LANG_RC_ERROR;
260 struct xmethod_worker *worker;
262 gdbpy_ref<> py_worker (PyIter_Next (iter.get ()));
263 if (py_worker == NULL)
265 if (PyErr_Occurred ())
267 gdbpy_print_stack ();
268 return EXT_LANG_RC_ERROR;
273 worker = new python_xmethod_worker (py_worker.get (),
276 dm_vec->emplace_back (worker);
281 struct xmethod_worker *worker;
283 worker = new python_xmethod_worker (match_result.get (),
285 dm_vec->emplace_back (worker);
289 return EXT_LANG_RC_OK;
292 /* See declaration. */
295 python_xmethod_worker::do_get_arg_types (int *nargs, type ***arg_types)
297 /* The gdbpy_enter object needs to be placed first, so that it's the last to
299 gdbpy_enter enter_py (get_current_arch (), current_language);
300 struct type *obj_type;
301 int i = 1, arg_count;
302 gdbpy_ref<> list_iter;
304 /* Set nargs to -1 so that any premature return from this function returns
305 an invalid/unusable number of arg types. */
308 gdbpy_ref<> get_arg_types_method
309 (PyObject_GetAttrString (m_py_worker, get_arg_types_method_name));
310 if (get_arg_types_method == NULL)
312 gdbpy_print_stack ();
313 return EXT_LANG_RC_ERROR;
316 gdbpy_ref<> py_argtype_list
317 (PyObject_CallMethodObjArgs (m_py_worker, py_get_arg_types_method_name,
319 if (py_argtype_list == NULL)
321 gdbpy_print_stack ();
322 return EXT_LANG_RC_ERROR;
325 if (py_argtype_list == Py_None)
327 else if (PySequence_Check (py_argtype_list.get ()))
329 arg_count = PySequence_Size (py_argtype_list.get ());
332 gdbpy_print_stack ();
333 return EXT_LANG_RC_ERROR;
336 list_iter.reset (PyObject_GetIter (py_argtype_list.get ()));
337 if (list_iter == NULL)
339 gdbpy_print_stack ();
340 return EXT_LANG_RC_ERROR;
346 /* Include the 'this' argument in the size. */
347 gdb::unique_xmalloc_ptr<struct type *> type_array
348 (XCNEWVEC (struct type *, arg_count + 1));
350 if (list_iter != NULL)
354 gdbpy_ref<> item (PyIter_Next (list_iter.get ()));
357 if (PyErr_Occurred ())
359 gdbpy_print_stack ();
360 return EXT_LANG_RC_ERROR;
365 struct type *arg_type = type_object_to_type (item.get ());
366 if (arg_type == NULL)
368 PyErr_SetString (PyExc_TypeError,
369 _("Arg type returned by the get_arg_types "
370 "method of a debug method worker object is "
371 "not a gdb.Type object."));
372 return EXT_LANG_RC_ERROR;
375 (type_array.get ())[i] = arg_type;
379 else if (arg_count == 1)
381 /* py_argtype_list is not actually a list but a single gdb.Type
383 struct type *arg_type = type_object_to_type (py_argtype_list.get ());
385 if (arg_type == NULL)
387 PyErr_SetString (PyExc_TypeError,
388 _("Arg type returned by the get_arg_types method "
389 "of an xmethod worker object is not a gdb.Type "
391 return EXT_LANG_RC_ERROR;
395 (type_array.get ())[i] = arg_type;
400 /* Add the type of 'this' as the first argument. The 'this' pointer should
401 be a 'const' value. Hence, create a 'const' variant of the 'this' pointer
403 obj_type = type_object_to_type (m_this_type);
404 (type_array.get ())[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
407 *arg_types = type_array.release ();
409 return EXT_LANG_RC_OK;
412 /* See declaration. */
415 python_xmethod_worker::do_get_result_type (value *obj, value **args, int nargs,
416 type **result_type_ptr)
418 struct type *obj_type, *this_type;
421 gdbpy_enter enter_py (get_current_arch (), current_language);
423 /* First see if there is a get_result_type method.
424 If not this could be an old xmethod (pre 7.9.1). */
425 gdbpy_ref<> get_result_type_method
426 (PyObject_GetAttrString (m_py_worker, get_result_type_method_name));
427 if (get_result_type_method == NULL)
430 *result_type_ptr = NULL;
431 return EXT_LANG_RC_OK;
434 obj_type = check_typedef (value_type (obj));
435 this_type = check_typedef (type_object_to_type (m_this_type));
436 if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
438 struct type *this_ptr = lookup_pointer_type (this_type);
440 if (!types_equal (obj_type, this_ptr))
441 obj = value_cast (this_ptr, obj);
443 else if (TYPE_IS_REFERENCE (obj_type))
445 struct type *this_ref
446 = lookup_reference_type (this_type, TYPE_CODE (obj_type));
448 if (!types_equal (obj_type, this_ref))
449 obj = value_cast (this_ref, obj);
453 if (!types_equal (obj_type, this_type))
454 obj = value_cast (this_type, obj);
456 gdbpy_ref<> py_value_obj (value_to_value_object (obj));
457 if (py_value_obj == NULL)
459 gdbpy_print_stack ();
460 return EXT_LANG_RC_ERROR;
463 gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
464 if (py_arg_tuple == NULL)
466 gdbpy_print_stack ();
467 return EXT_LANG_RC_ERROR;
470 /* PyTuple_SET_ITEM steals the reference of the element, hence the
472 PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
474 for (i = 0; i < nargs; i++)
476 PyObject *py_value_arg = value_to_value_object (args[i]);
478 if (py_value_arg == NULL)
480 gdbpy_print_stack ();
481 return EXT_LANG_RC_ERROR;
483 PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
486 gdbpy_ref<> py_result_type
487 (PyObject_CallObject (get_result_type_method.get (), py_arg_tuple.get ()));
488 if (py_result_type == NULL)
490 gdbpy_print_stack ();
491 return EXT_LANG_RC_ERROR;
494 *result_type_ptr = type_object_to_type (py_result_type.get ());
495 if (*result_type_ptr == NULL)
497 PyErr_SetString (PyExc_TypeError,
498 _("Type returned by the get_result_type method of an"
499 " xmethod worker object is not a gdb.Type object."));
500 gdbpy_print_stack ();
501 return EXT_LANG_RC_ERROR;
504 return EXT_LANG_RC_OK;
507 /* See declaration. */
510 python_xmethod_worker::invoke (struct value *obj, struct value **args,
513 gdbpy_enter enter_py (get_current_arch (), current_language);
516 struct type *obj_type, *this_type;
517 struct value *res = NULL;
519 obj_type = check_typedef (value_type (obj));
520 this_type = check_typedef (type_object_to_type (m_this_type));
521 if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
523 struct type *this_ptr = lookup_pointer_type (this_type);
525 if (!types_equal (obj_type, this_ptr))
526 obj = value_cast (this_ptr, obj);
528 else if (TYPE_IS_REFERENCE (obj_type))
530 struct type *this_ref
531 = lookup_reference_type (this_type, TYPE_CODE (obj_type));
533 if (!types_equal (obj_type, this_ref))
534 obj = value_cast (this_ref, obj);
538 if (!types_equal (obj_type, this_type))
539 obj = value_cast (this_type, obj);
541 gdbpy_ref<> py_value_obj (value_to_value_object (obj));
542 if (py_value_obj == NULL)
544 gdbpy_print_stack ();
545 error (_("Error while executing Python code."));
548 gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
549 if (py_arg_tuple == NULL)
551 gdbpy_print_stack ();
552 error (_("Error while executing Python code."));
555 /* PyTuple_SET_ITEM steals the reference of the element, hence the
557 PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
559 for (i = 0; i < nargs; i++)
561 PyObject *py_value_arg = value_to_value_object (args[i]);
563 if (py_value_arg == NULL)
565 gdbpy_print_stack ();
566 error (_("Error while executing Python code."));
569 PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
572 gdbpy_ref<> py_result (PyObject_CallObject (m_py_worker,
573 py_arg_tuple.get ()));
574 if (py_result == NULL)
576 gdbpy_print_stack ();
577 error (_("Error while executing Python code."));
580 if (py_result != Py_None)
582 res = convert_value_from_python (py_result.get ());
585 gdbpy_print_stack ();
586 error (_("Error while executing Python code."));
591 res = allocate_value (lookup_typename (python_language, python_gdbarch,
598 python_xmethod_worker::python_xmethod_worker (PyObject *py_worker,
600 : xmethod_worker (&extension_language_python),
601 m_py_worker (py_worker), m_this_type (this_type)
603 gdb_assert (m_py_worker != NULL && m_this_type != NULL);
605 Py_INCREF (py_worker);
606 Py_INCREF (this_type);
610 gdbpy_initialize_xmethods (void)
612 py_match_method_name = PyString_FromString (match_method_name);
613 if (py_match_method_name == NULL)
616 py_get_arg_types_method_name
617 = PyString_FromString (get_arg_types_method_name);
618 if (py_get_arg_types_method_name == NULL)