Home | History | Annotate | Line # | Download | only in python
py-xmethods.c revision 1.1.1.6
      1 /* Support for debug methods in Python.
      2 
      3    Copyright (C) 2013-2023 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 #include "defs.h"
     21 #include "arch-utils.h"
     22 #include "extension-priv.h"
     23 #include "objfiles.h"
     24 #include "value.h"
     25 #include "language.h"
     26 
     27 #include "python.h"
     28 #include "python-internal.h"
     29 
     30 static const char enabled_field_name[] = "enabled";
     31 static const char match_method_name[] = "match";
     32 static const char get_arg_types_method_name[] = "get_arg_types";
     33 static const char get_result_type_method_name[] = "get_result_type";
     34 static const char matchers_attr_str[] = "xmethods";
     35 
     36 static PyObject *py_match_method_name = NULL;
     37 static PyObject *py_get_arg_types_method_name = NULL;
     38 
     39 struct python_xmethod_worker : xmethod_worker
     40 {
     41   python_xmethod_worker (PyObject *worker, PyObject *this_type);
     42   ~python_xmethod_worker ();
     43 
     44   DISABLE_COPY_AND_ASSIGN (python_xmethod_worker);
     45 
     46   /* Implementation of xmethod_worker::invoke for Python.  */
     47 
     48   value *invoke (value *obj, gdb::array_view<value *> args) override;
     49 
     50   /* Implementation of xmethod_worker::do_get_arg_types for Python.  */
     51 
     52   ext_lang_rc do_get_arg_types (std::vector<type *> *type_args) override;
     53 
     54   /* Implementation of xmethod_worker::do_get_result_type for Python.
     55 
     56      For backward compatibility with 7.9, which did not support getting the
     57      result type, if the get_result_type operation is not provided by WORKER
     58      then EXT_LANG_RC_OK is returned and NULL is returned in *RESULT_TYPE.  */
     59 
     60   ext_lang_rc do_get_result_type (value *obj, gdb::array_view<value *> args,
     61 				  type **result_type_ptr) override;
     62 
     63 private:
     64 
     65   PyObject *m_py_worker;
     66   PyObject *m_this_type;
     67 };
     68 
     69 python_xmethod_worker::~python_xmethod_worker ()
     70 {
     71   /* We don't do much here, but we still need the GIL.  */
     72   gdbpy_enter enter_py;
     73 
     74   Py_DECREF (m_py_worker);
     75   Py_DECREF (m_this_type);
     76 }
     77 
     78 /* Invoke the "match" method of the MATCHER and return a new reference
     79    to the result.  Returns NULL on error.  */
     80 
     81 static PyObject *
     82 invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
     83 		     const char *xmethod_name)
     84 {
     85   int enabled;
     86 
     87   gdbpy_ref<> enabled_field (PyObject_GetAttrString (matcher,
     88 						     enabled_field_name));
     89   if (enabled_field == NULL)
     90     return NULL;
     91 
     92   enabled = PyObject_IsTrue (enabled_field.get ());
     93   if (enabled == -1)
     94     return NULL;
     95   if (enabled == 0)
     96     {
     97       /* Return 'None' if the matcher is not enabled.  */
     98       Py_RETURN_NONE;
     99     }
    100 
    101   gdbpy_ref<> match_method (PyObject_GetAttrString (matcher,
    102 						    match_method_name));
    103   if (match_method == NULL)
    104     return NULL;
    105 
    106   gdbpy_ref<> py_xmethod_name (PyUnicode_FromString (xmethod_name));
    107   if (py_xmethod_name == NULL)
    108     return NULL;
    109 
    110   return PyObject_CallMethodObjArgs (matcher, py_match_method_name,
    111 				     py_obj_type, py_xmethod_name.get (),
    112 				     NULL);
    113 }
    114 
    115 /* Implementation of get_matching_xmethod_workers for Python.  */
    116 
    117 enum ext_lang_rc
    118 gdbpy_get_matching_xmethod_workers
    119   (const struct extension_language_defn *extlang,
    120    struct type *obj_type, const char *method_name,
    121    std::vector<xmethod_worker_up> *dm_vec)
    122 {
    123   gdb_assert (obj_type != NULL && method_name != NULL);
    124 
    125   gdbpy_enter enter_py;
    126 
    127   gdbpy_ref<> py_type (type_to_type_object (obj_type));
    128   if (py_type == NULL)
    129     {
    130       gdbpy_print_stack ();
    131       return EXT_LANG_RC_ERROR;
    132     }
    133 
    134   /* Create an empty list of debug methods.  */
    135   gdbpy_ref<> py_xmethod_matcher_list (PyList_New (0));
    136   if (py_xmethod_matcher_list == NULL)
    137     {
    138       gdbpy_print_stack ();
    139       return EXT_LANG_RC_ERROR;
    140     }
    141 
    142   /* Gather debug method matchers registered with the object files.
    143      This could be done differently by iterating over each objfile's matcher
    144      list individually, but there's no data yet to show it's needed.  */
    145   for (objfile *objfile : current_program_space->objfiles ())
    146     {
    147       gdbpy_ref<> py_objfile = objfile_to_objfile_object (objfile);
    148 
    149       if (py_objfile == NULL)
    150 	{
    151 	  gdbpy_print_stack ();
    152 	  return EXT_LANG_RC_ERROR;
    153 	}
    154 
    155       gdbpy_ref<> objfile_matchers (objfpy_get_xmethods (py_objfile.get (),
    156 							 NULL));
    157       gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
    158 					   objfile_matchers.get ()));
    159       if (temp == NULL)
    160 	{
    161 	  gdbpy_print_stack ();
    162 	  return EXT_LANG_RC_ERROR;
    163 	}
    164 
    165       py_xmethod_matcher_list = std::move (temp);
    166     }
    167 
    168   /* Gather debug methods matchers registered with the current program
    169      space.  */
    170   gdbpy_ref<> py_progspace = pspace_to_pspace_object (current_program_space);
    171   if (py_progspace != NULL)
    172     {
    173       gdbpy_ref<> pspace_matchers (pspy_get_xmethods (py_progspace.get (),
    174 						      NULL));
    175 
    176       gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
    177 					   pspace_matchers.get ()));
    178       if (temp == NULL)
    179 	{
    180 	  gdbpy_print_stack ();
    181 	  return EXT_LANG_RC_ERROR;
    182 	}
    183 
    184       py_xmethod_matcher_list = std::move (temp);
    185     }
    186   else
    187     {
    188       gdbpy_print_stack ();
    189       return EXT_LANG_RC_ERROR;
    190     }
    191 
    192   /* Gather debug method matchers registered globally.  */
    193   if (gdb_python_module != NULL
    194       && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
    195     {
    196       gdbpy_ref<> gdb_matchers (PyObject_GetAttrString (gdb_python_module,
    197 							matchers_attr_str));
    198       if (gdb_matchers != NULL)
    199 	{
    200 	  gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
    201 					       gdb_matchers.get ()));
    202 	  if (temp == NULL)
    203 	    {
    204 	      gdbpy_print_stack ();
    205 	      return EXT_LANG_RC_ERROR;
    206 	    }
    207 
    208 	  py_xmethod_matcher_list = std::move (temp);
    209 	}
    210       else
    211 	{
    212 	  gdbpy_print_stack ();
    213 	  return EXT_LANG_RC_ERROR;
    214 	}
    215     }
    216 
    217   gdbpy_ref<> list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
    218   if (list_iter == NULL)
    219     {
    220       gdbpy_print_stack ();
    221       return EXT_LANG_RC_ERROR;
    222     }
    223   while (true)
    224     {
    225       gdbpy_ref<> matcher (PyIter_Next (list_iter.get ()));
    226       if (matcher == NULL)
    227 	{
    228 	  if (PyErr_Occurred ())
    229 	    {
    230 	      gdbpy_print_stack ();
    231 	      return EXT_LANG_RC_ERROR;
    232 	    }
    233 	  break;
    234 	}
    235 
    236       gdbpy_ref<> match_result (invoke_match_method (matcher.get (),
    237 						     py_type.get (),
    238 						     method_name));
    239 
    240       if (match_result == NULL)
    241 	{
    242 	  gdbpy_print_stack ();
    243 	  return EXT_LANG_RC_ERROR;
    244 	}
    245       if (match_result == Py_None)
    246 	; /* This means there was no match.  */
    247       else if (PySequence_Check (match_result.get ()))
    248 	{
    249 	  gdbpy_ref<> iter (PyObject_GetIter (match_result.get ()));
    250 
    251 	  if (iter == NULL)
    252 	    {
    253 	      gdbpy_print_stack ();
    254 	      return EXT_LANG_RC_ERROR;
    255 	    }
    256 	  while (true)
    257 	    {
    258 	      struct xmethod_worker *worker;
    259 
    260 	      gdbpy_ref<> py_worker (PyIter_Next (iter.get ()));
    261 	      if (py_worker == NULL)
    262 		{
    263 		  if (PyErr_Occurred ())
    264 		    {
    265 		      gdbpy_print_stack ();
    266 		      return EXT_LANG_RC_ERROR;
    267 		    }
    268 		  break;
    269 		}
    270 
    271 	      worker = new python_xmethod_worker (py_worker.get (),
    272 						  py_type.get ());
    273 
    274 	      dm_vec->emplace_back (worker);
    275 	    }
    276 	}
    277       else
    278 	{
    279 	  struct xmethod_worker *worker;
    280 
    281 	  worker = new python_xmethod_worker (match_result.get (),
    282 					      py_type.get ());
    283 	  dm_vec->emplace_back (worker);
    284 	}
    285     }
    286 
    287   return EXT_LANG_RC_OK;
    288 }
    289 
    290 /* See declaration.  */
    291 
    292 ext_lang_rc
    293 python_xmethod_worker::do_get_arg_types (std::vector<type *> *arg_types)
    294 {
    295   /* The gdbpy_enter object needs to be placed first, so that it's the last to
    296      be destroyed.  */
    297   gdbpy_enter enter_py;
    298   struct type *obj_type;
    299   int i = 1, arg_count;
    300   gdbpy_ref<> list_iter;
    301 
    302   gdbpy_ref<> get_arg_types_method
    303     (PyObject_GetAttrString (m_py_worker, get_arg_types_method_name));
    304   if (get_arg_types_method == NULL)
    305     {
    306       gdbpy_print_stack ();
    307       return EXT_LANG_RC_ERROR;
    308     }
    309 
    310   gdbpy_ref<> py_argtype_list
    311     (PyObject_CallMethodObjArgs (m_py_worker, py_get_arg_types_method_name,
    312 				 NULL));
    313   if (py_argtype_list == NULL)
    314     {
    315       gdbpy_print_stack ();
    316       return EXT_LANG_RC_ERROR;
    317     }
    318 
    319   if (py_argtype_list == Py_None)
    320     arg_count = 0;
    321   else if (PySequence_Check (py_argtype_list.get ()))
    322     {
    323       arg_count = PySequence_Size (py_argtype_list.get ());
    324       if (arg_count == -1)
    325 	{
    326 	  gdbpy_print_stack ();
    327 	  return EXT_LANG_RC_ERROR;
    328 	}
    329 
    330       list_iter.reset (PyObject_GetIter (py_argtype_list.get ()));
    331       if (list_iter == NULL)
    332 	{
    333 	  gdbpy_print_stack ();
    334 	  return EXT_LANG_RC_ERROR;
    335 	}
    336     }
    337   else
    338     arg_count = 1;
    339 
    340   /* Include the 'this' argument in the size.  */
    341   arg_types->resize (arg_count + 1);
    342   i = 1;
    343   if (list_iter != NULL)
    344     {
    345       while (true)
    346 	{
    347 	  gdbpy_ref<> item (PyIter_Next (list_iter.get ()));
    348 	  if (item == NULL)
    349 	    {
    350 	      if (PyErr_Occurred ())
    351 		{
    352 		  gdbpy_print_stack ();
    353 		  return EXT_LANG_RC_ERROR;
    354 		}
    355 	      break;
    356 	    }
    357 
    358 	  struct type *arg_type = type_object_to_type (item.get ());
    359 	  if (arg_type == NULL)
    360 	    {
    361 	      PyErr_SetString (PyExc_TypeError,
    362 			       _("Arg type returned by the get_arg_types "
    363 				 "method of a debug method worker object is "
    364 				 "not a gdb.Type object."));
    365 	      return EXT_LANG_RC_ERROR;
    366 	    }
    367 
    368 	  (*arg_types)[i] = arg_type;
    369 	  i++;
    370 	}
    371     }
    372   else if (arg_count == 1)
    373     {
    374       /* py_argtype_list is not actually a list but a single gdb.Type
    375 	 object.  */
    376       struct type *arg_type = type_object_to_type (py_argtype_list.get ());
    377 
    378       if (arg_type == NULL)
    379 	{
    380 	  PyErr_SetString (PyExc_TypeError,
    381 			   _("Arg type returned by the get_arg_types method "
    382 			     "of an xmethod worker object is not a gdb.Type "
    383 			     "object."));
    384 	  return EXT_LANG_RC_ERROR;
    385 	}
    386       else
    387 	{
    388 	  (*arg_types)[i] = arg_type;
    389 	  i++;
    390 	}
    391     }
    392 
    393   /* Add the type of 'this' as the first argument.  The 'this' pointer should
    394      be a 'const' value.  Hence, create a 'const' variant of the 'this' pointer
    395      type.  */
    396   obj_type = type_object_to_type (m_this_type);
    397   (*arg_types)[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
    398 				  NULL);
    399 
    400   return EXT_LANG_RC_OK;
    401 }
    402 
    403 /* See declaration.  */
    404 
    405 ext_lang_rc
    406 python_xmethod_worker::do_get_result_type (value *obj,
    407 					   gdb::array_view<value *> args,
    408 					   type **result_type_ptr)
    409 {
    410   struct type *obj_type, *this_type;
    411   int i;
    412 
    413   gdbpy_enter enter_py;
    414 
    415   /* First see if there is a get_result_type method.
    416      If not this could be an old xmethod (pre 7.9.1).  */
    417   gdbpy_ref<> get_result_type_method
    418     (PyObject_GetAttrString (m_py_worker, get_result_type_method_name));
    419   if (get_result_type_method == NULL)
    420     {
    421       PyErr_Clear ();
    422       *result_type_ptr = NULL;
    423       return EXT_LANG_RC_OK;
    424     }
    425 
    426   obj_type = check_typedef (value_type (obj));
    427   this_type = check_typedef (type_object_to_type (m_this_type));
    428   if (obj_type->code () == TYPE_CODE_PTR)
    429     {
    430       struct type *this_ptr = lookup_pointer_type (this_type);
    431 
    432       if (!types_equal (obj_type, this_ptr))
    433 	obj = value_cast (this_ptr, obj);
    434     }
    435   else if (TYPE_IS_REFERENCE (obj_type))
    436     {
    437       struct type *this_ref
    438 	= lookup_reference_type (this_type, obj_type->code ());
    439 
    440       if (!types_equal (obj_type, this_ref))
    441 	obj = value_cast (this_ref, obj);
    442     }
    443   else
    444     {
    445       if (!types_equal (obj_type, this_type))
    446 	obj = value_cast (this_type, obj);
    447     }
    448   gdbpy_ref<> py_value_obj (value_to_value_object (obj));
    449   if (py_value_obj == NULL)
    450     {
    451       gdbpy_print_stack ();
    452       return EXT_LANG_RC_ERROR;
    453     }
    454 
    455   gdbpy_ref<> py_arg_tuple (PyTuple_New (args.size () + 1));
    456   if (py_arg_tuple == NULL)
    457     {
    458       gdbpy_print_stack ();
    459       return EXT_LANG_RC_ERROR;
    460     }
    461 
    462   /* PyTuple_SET_ITEM steals the reference of the element, hence the
    463      release.  */
    464   PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
    465 
    466   for (i = 0; i < args.size (); i++)
    467     {
    468       PyObject *py_value_arg = value_to_value_object (args[i]);
    469 
    470       if (py_value_arg == NULL)
    471 	{
    472 	  gdbpy_print_stack ();
    473 	  return EXT_LANG_RC_ERROR;
    474 	}
    475       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
    476     }
    477 
    478   gdbpy_ref<> py_result_type
    479     (PyObject_CallObject (get_result_type_method.get (), py_arg_tuple.get ()));
    480   if (py_result_type == NULL)
    481     {
    482       gdbpy_print_stack ();
    483       return EXT_LANG_RC_ERROR;
    484     }
    485 
    486   *result_type_ptr = type_object_to_type (py_result_type.get ());
    487   if (*result_type_ptr == NULL)
    488     {
    489       PyErr_SetString (PyExc_TypeError,
    490 		       _("Type returned by the get_result_type method of an"
    491 			 " xmethod worker object is not a gdb.Type object."));
    492       gdbpy_print_stack ();
    493       return EXT_LANG_RC_ERROR;
    494     }
    495 
    496   return EXT_LANG_RC_OK;
    497 }
    498 
    499 /* See declaration.  */
    500 
    501 struct value *
    502 python_xmethod_worker::invoke (struct value *obj,
    503 			       gdb::array_view<value *> args)
    504 {
    505   gdbpy_enter enter_py;
    506 
    507   int i;
    508   struct type *obj_type, *this_type;
    509   struct value *res = NULL;
    510 
    511   obj_type = check_typedef (value_type (obj));
    512   this_type = check_typedef (type_object_to_type (m_this_type));
    513   if (obj_type->code () == TYPE_CODE_PTR)
    514     {
    515       struct type *this_ptr = lookup_pointer_type (this_type);
    516 
    517       if (!types_equal (obj_type, this_ptr))
    518 	obj = value_cast (this_ptr, obj);
    519     }
    520   else if (TYPE_IS_REFERENCE (obj_type))
    521     {
    522       struct type *this_ref
    523 	= lookup_reference_type (this_type, obj_type->code ());
    524 
    525       if (!types_equal (obj_type, this_ref))
    526 	obj = value_cast (this_ref, obj);
    527     }
    528   else
    529     {
    530       if (!types_equal (obj_type, this_type))
    531 	obj = value_cast (this_type, obj);
    532     }
    533   gdbpy_ref<> py_value_obj (value_to_value_object (obj));
    534   if (py_value_obj == NULL)
    535     {
    536       gdbpy_print_stack ();
    537       error (_("Error while executing Python code."));
    538     }
    539 
    540   gdbpy_ref<> py_arg_tuple (PyTuple_New (args.size () + 1));
    541   if (py_arg_tuple == NULL)
    542     {
    543       gdbpy_print_stack ();
    544       error (_("Error while executing Python code."));
    545     }
    546 
    547   /* PyTuple_SET_ITEM steals the reference of the element, hence the
    548      release.  */
    549   PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
    550 
    551   for (i = 0; i < args.size (); i++)
    552     {
    553       PyObject *py_value_arg = value_to_value_object (args[i]);
    554 
    555       if (py_value_arg == NULL)
    556 	{
    557 	  gdbpy_print_stack ();
    558 	  error (_("Error while executing Python code."));
    559 	}
    560 
    561       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
    562     }
    563 
    564   gdbpy_ref<> py_result (PyObject_CallObject (m_py_worker,
    565 					      py_arg_tuple.get ()));
    566   if (py_result == NULL)
    567     {
    568       gdbpy_print_stack ();
    569       error (_("Error while executing Python code."));
    570     }
    571 
    572   if (py_result != Py_None)
    573     {
    574       res = convert_value_from_python (py_result.get ());
    575       if (res == NULL)
    576 	{
    577 	  gdbpy_print_stack ();
    578 	  error (_("Error while executing Python code."));
    579 	}
    580     }
    581   else
    582     {
    583       res = allocate_value (lookup_typename (current_language,
    584 					     "void", NULL, 0));
    585     }
    586 
    587   return res;
    588 }
    589 
    590 python_xmethod_worker::python_xmethod_worker (PyObject *py_worker,
    591 					       PyObject *this_type)
    592 : xmethod_worker (&extension_language_python),
    593   m_py_worker (py_worker), m_this_type (this_type)
    594 {
    595   gdb_assert (m_py_worker != NULL && m_this_type != NULL);
    596 
    597   Py_INCREF (py_worker);
    598   Py_INCREF (this_type);
    599 }
    600 
    601 int
    602 gdbpy_initialize_xmethods (void)
    603 {
    604   py_match_method_name = PyUnicode_FromString (match_method_name);
    605   if (py_match_method_name == NULL)
    606     return -1;
    607 
    608   py_get_arg_types_method_name
    609     = PyUnicode_FromString (get_arg_types_method_name);
    610   if (py_get_arg_types_method_name == NULL)
    611     return -1;
    612 
    613   return 1;
    614 }
    615