Home | History | Annotate | Line # | Download | only in python
py-inferior.c revision 1.12
      1 /* Python interface to inferiors.
      2 
      3    Copyright (C) 2009-2024 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 "auto-load.h"
     21 #include "gdbcore.h"
     22 #include "gdbthread.h"
     23 #include "inferior.h"
     24 #include "objfiles.h"
     25 #include "observable.h"
     26 #include "python-internal.h"
     27 #include "arch-utils.h"
     28 #include "language.h"
     29 #include "gdbsupport/gdb_signals.h"
     30 #include "py-event.h"
     31 #include "py-stopevent.h"
     32 #include "progspace-and-thread.h"
     33 #include <unordered_map>
     34 
     35 using thread_map_t
     36   = std::unordered_map<thread_info *, gdbpy_ref<thread_object>>;
     37 
     38 struct inferior_object
     39 {
     40   PyObject_HEAD
     41 
     42   /* The inferior we represent.  */
     43   struct inferior *inferior;
     44 
     45   /* thread_object instances under this inferior.  This owns a
     46      reference to each object it contains.  */
     47   thread_map_t *threads;
     48 
     49   /* Dictionary holding user-added attributes.
     50      This is the __dict__ attribute of the object.  */
     51   PyObject *dict;
     52 };
     53 
     54 extern PyTypeObject inferior_object_type
     55     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
     56 
     57 /* Deleter to clean up when an inferior is removed.  */
     58 struct infpy_deleter
     59 {
     60   void operator() (inferior_object *obj)
     61   {
     62     if (!gdb_python_initialized)
     63       return;
     64 
     65     gdbpy_enter enter_py;
     66     gdbpy_ref<inferior_object> inf_obj (obj);
     67 
     68     inf_obj->inferior = NULL;
     69 
     70     delete inf_obj->threads;
     71   }
     72 };
     73 
     74 static const registry<inferior>::key<inferior_object, infpy_deleter>
     75      infpy_inf_data_key;
     76 
     77 /* Require that INFERIOR be a valid inferior ID.  */
     78 #define INFPY_REQUIRE_VALID(Inferior)				\
     79   do {								\
     80     if (!Inferior->inferior)					\
     81       {								\
     82 	PyErr_SetString (PyExc_RuntimeError,			\
     83 			 _("Inferior no longer exists."));	\
     84 	return NULL;						\
     85       }								\
     86   } while (0)
     87 
     88 static void
     89 python_on_normal_stop (struct bpstat *bs, int print_frame)
     90 {
     91   enum gdb_signal stop_signal;
     92 
     93   if (!gdb_python_initialized)
     94     return;
     95 
     96   if (inferior_ptid == null_ptid)
     97     return;
     98 
     99   stop_signal = inferior_thread ()->stop_signal ();
    100 
    101   gdbpy_enter enter_py;
    102 
    103   if (emit_stop_event (bs, stop_signal) < 0)
    104     gdbpy_print_stack ();
    105 }
    106 
    107 static void
    108 python_on_resume (ptid_t ptid)
    109 {
    110   if (!gdb_python_initialized)
    111     return;
    112 
    113   gdbpy_enter enter_py (current_inferior ()->arch ());
    114 
    115   if (emit_continue_event (ptid) < 0)
    116     gdbpy_print_stack ();
    117 }
    118 
    119 /* Callback, registered as an observer, that notifies Python listeners
    120    when an inferior function call is about to be made. */
    121 
    122 static void
    123 python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
    124 {
    125   gdbpy_enter enter_py (current_inferior ()->arch ());
    126 
    127   if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
    128     gdbpy_print_stack ();
    129 }
    130 
    131 /* Callback, registered as an observer, that notifies Python listeners
    132    when an inferior function call has completed. */
    133 
    134 static void
    135 python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
    136 {
    137   gdbpy_enter enter_py (current_inferior ()->arch ());
    138 
    139   if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
    140     gdbpy_print_stack ();
    141 }
    142 
    143 /* Callback, registered as an observer, that notifies Python listeners
    144    when a part of memory has been modified by user action (eg via a
    145    'set' command). */
    146 
    147 static void
    148 python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
    149 {
    150   gdbpy_enter enter_py (current_inferior ()->arch ());
    151 
    152   if (emit_memory_changed_event (addr, len) < 0)
    153     gdbpy_print_stack ();
    154 }
    155 
    156 /* Callback, registered as an observer, that notifies Python listeners
    157    when a register has been modified by user action (eg via a 'set'
    158    command). */
    159 
    160 static void
    161 python_on_register_change (const frame_info_ptr &frame, int regnum)
    162 {
    163   gdbpy_enter enter_py (current_inferior ()->arch ());
    164 
    165   if (emit_register_changed_event (frame, regnum) < 0)
    166     gdbpy_print_stack ();
    167 }
    168 
    169 static void
    170 python_inferior_exit (struct inferior *inf)
    171 {
    172   const LONGEST *exit_code = NULL;
    173 
    174   if (!gdb_python_initialized)
    175     return;
    176 
    177   gdbpy_enter enter_py (current_inferior ()->arch ());
    178 
    179   if (inf->has_exit_code)
    180     exit_code = &inf->exit_code;
    181 
    182   if (emit_exited_event (exit_code, inf) < 0)
    183     gdbpy_print_stack ();
    184 }
    185 
    186 /* Callback used to notify Python listeners about new objfiles loaded in the
    187    inferior.  OBJFILE may be NULL which means that the objfile list has been
    188    cleared (emptied).  */
    189 
    190 static void
    191 python_new_objfile (struct objfile *objfile)
    192 {
    193   if (!gdb_python_initialized)
    194     return;
    195 
    196   gdbpy_enter enter_py (objfile->arch ());
    197 
    198   if (emit_new_objfile_event (objfile) < 0)
    199     gdbpy_print_stack ();
    200 }
    201 
    202 static void
    203 python_all_objfiles_removed (program_space *pspace)
    204 {
    205   if (!gdb_python_initialized)
    206     return;
    207 
    208   gdbpy_enter enter_py (current_inferior ()->arch ());
    209 
    210   if (emit_clear_objfiles_event (pspace) < 0)
    211     gdbpy_print_stack ();
    212 }
    213 
    214 /* Emit a Python event when an objfile is about to be removed.  */
    215 
    216 static void
    217 python_free_objfile (struct objfile *objfile)
    218 {
    219   if (!gdb_python_initialized)
    220     return;
    221 
    222   gdbpy_enter enter_py (objfile->arch ());
    223 
    224   if (emit_free_objfile_event (objfile) < 0)
    225     gdbpy_print_stack ();
    226 }
    227 
    228 /* Return a reference to the Python object of type Inferior
    229    representing INFERIOR.  If the object has already been created,
    230    return it and increment the reference count,  otherwise, create it.
    231    Return NULL on failure.  */
    232 
    233 gdbpy_ref<inferior_object>
    234 inferior_to_inferior_object (struct inferior *inferior)
    235 {
    236   inferior_object *inf_obj;
    237 
    238   inf_obj = infpy_inf_data_key.get (inferior);
    239   if (!inf_obj)
    240     {
    241       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
    242       if (!inf_obj)
    243 	return NULL;
    244 
    245       inf_obj->inferior = inferior;
    246       inf_obj->threads = new thread_map_t ();
    247       inf_obj->dict = PyDict_New ();
    248       if (inf_obj->dict == nullptr)
    249 	return nullptr;
    250 
    251       /* PyObject_New initializes the new object with a refcount of 1.  This
    252 	 counts for the reference we are keeping in the inferior data.  */
    253       infpy_inf_data_key.set (inferior, inf_obj);
    254     }
    255 
    256   /* We are returning a new reference.  */
    257   gdb_assert (inf_obj != nullptr);
    258   return gdbpy_ref<inferior_object>::new_reference (inf_obj);
    259 }
    260 
    261 /* Called when a new inferior is created.  Notifies any Python event
    262    listeners.  */
    263 static void
    264 python_new_inferior (struct inferior *inf)
    265 {
    266   if (!gdb_python_initialized)
    267     return;
    268 
    269   gdbpy_enter enter_py;
    270 
    271   if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
    272     return;
    273 
    274   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
    275   if (inf_obj == NULL)
    276     {
    277       gdbpy_print_stack ();
    278       return;
    279     }
    280 
    281   gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
    282   if (event == NULL
    283       || evpy_add_attribute (event.get (), "inferior",
    284 			     (PyObject *) inf_obj.get ()) < 0
    285       || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
    286     gdbpy_print_stack ();
    287 }
    288 
    289 /* Called when an inferior is removed.  Notifies any Python event
    290    listeners.  */
    291 static void
    292 python_inferior_deleted (struct inferior *inf)
    293 {
    294   if (!gdb_python_initialized)
    295     return;
    296 
    297   gdbpy_enter enter_py;
    298 
    299   if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
    300     return;
    301 
    302   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
    303   if (inf_obj == NULL)
    304     {
    305       gdbpy_print_stack ();
    306       return;
    307     }
    308 
    309   gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
    310   if (event == NULL
    311       || evpy_add_attribute (event.get (), "inferior",
    312 			     (PyObject *) inf_obj.get ()) < 0
    313       || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
    314     gdbpy_print_stack ();
    315 }
    316 
    317 gdbpy_ref<>
    318 thread_to_thread_object (thread_info *thr)
    319 {
    320   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
    321   if (inf_obj == NULL)
    322     return NULL;
    323 
    324   auto thread_it = inf_obj->threads->find (thr);
    325   if (thread_it != inf_obj->threads->end ())
    326     return gdbpy_ref<>::new_reference
    327       ((PyObject *) (thread_it->second.get ()));
    328 
    329   PyErr_SetString (PyExc_SystemError,
    330 		   _("could not find gdb thread object"));
    331   return NULL;
    332 }
    333 
    334 static void
    335 add_thread_object (struct thread_info *tp)
    336 {
    337   inferior_object *inf_obj;
    338 
    339   if (!gdb_python_initialized)
    340     return;
    341 
    342   gdbpy_enter enter_py;
    343 
    344   gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
    345   if (thread_obj == NULL)
    346     {
    347       gdbpy_print_stack ();
    348       return;
    349     }
    350 
    351   inf_obj = (inferior_object *) thread_obj->inf_obj;
    352 
    353   auto ins_result = inf_obj->threads->emplace
    354     (thread_map_t::value_type (tp, std::move (thread_obj)));
    355 
    356   if (!ins_result.second)
    357     return;
    358 
    359   if (evregpy_no_listeners_p (gdb_py_events.new_thread))
    360     return;
    361 
    362   gdbpy_ref<> event = create_thread_event_object
    363     (&new_thread_event_object_type,
    364      (PyObject *) ins_result.first->second.get ());
    365 
    366   if (event == NULL
    367       || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
    368     gdbpy_print_stack ();
    369 }
    370 
    371 static void
    372 delete_thread_object (thread_info *tp,
    373 		      std::optional<ULONGEST> /* exit_code */,
    374 		      bool /* silent */)
    375 {
    376   if (!gdb_python_initialized)
    377     return;
    378 
    379   gdbpy_enter enter_py;
    380 
    381   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
    382   if (inf_obj == NULL)
    383     return;
    384 
    385   if (emit_thread_exit_event (tp) < 0)
    386     gdbpy_print_stack ();
    387 
    388   auto it = inf_obj->threads->find (tp);
    389   if (it != inf_obj->threads->end ())
    390     {
    391       /* Some python code can still hold a reference to the thread_object
    392 	 instance.   Make sure to remove the link to the associated
    393 	 thread_info object as it will be freed soon.  This makes the python
    394 	 object invalid (i.e. gdb.InfThread.is_valid returns False).  */
    395       it->second->thread = nullptr;
    396       inf_obj->threads->erase (it);
    397     }
    398 }
    399 
    400 static PyObject *
    401 infpy_threads (PyObject *self, PyObject *args)
    402 {
    403   int i = 0;
    404   inferior_object *inf_obj = (inferior_object *) self;
    405   PyObject *tuple;
    406 
    407   INFPY_REQUIRE_VALID (inf_obj);
    408 
    409   try
    410     {
    411       update_thread_list ();
    412     }
    413   catch (const gdb_exception &except)
    414     {
    415       return gdbpy_handle_gdb_exception (nullptr, except);
    416     }
    417 
    418   tuple = PyTuple_New (inf_obj->threads->size ());
    419   if (!tuple)
    420     return NULL;
    421 
    422   for (const thread_map_t::value_type &entry : *inf_obj->threads)
    423     {
    424       PyObject *thr = (PyObject *) entry.second.get ();
    425       Py_INCREF (thr);
    426       PyTuple_SET_ITEM (tuple, i, thr);
    427       i = i + 1;
    428     }
    429 
    430   return tuple;
    431 }
    432 
    433 static PyObject *
    434 infpy_get_num (PyObject *self, void *closure)
    435 {
    436   inferior_object *inf = (inferior_object *) self;
    437 
    438   INFPY_REQUIRE_VALID (inf);
    439 
    440   return gdb_py_object_from_longest (inf->inferior->num).release ();
    441 }
    442 
    443 /* Return the gdb.TargetConnection object for this inferior, or None if a
    444    connection does not exist.  */
    445 
    446 static PyObject *
    447 infpy_get_connection (PyObject *self, void *closure)
    448 {
    449   inferior_object *inf = (inferior_object *) self;
    450 
    451   INFPY_REQUIRE_VALID (inf);
    452 
    453   process_stratum_target *target = inf->inferior->process_target ();
    454   return target_to_connection_object (target).release ();
    455 }
    456 
    457 /* Return the connection number of the given inferior, or None if a
    458    connection does not exist.  */
    459 
    460 static PyObject *
    461 infpy_get_connection_num (PyObject *self, void *closure)
    462 {
    463   inferior_object *inf = (inferior_object *) self;
    464 
    465   INFPY_REQUIRE_VALID (inf);
    466 
    467   process_stratum_target *target = inf->inferior->process_target ();
    468   if (target == nullptr)
    469     Py_RETURN_NONE;
    470 
    471   return gdb_py_object_from_longest (target->connection_number).release ();
    472 }
    473 
    474 static PyObject *
    475 infpy_get_pid (PyObject *self, void *closure)
    476 {
    477   inferior_object *inf = (inferior_object *) self;
    478 
    479   INFPY_REQUIRE_VALID (inf);
    480 
    481   return gdb_py_object_from_longest (inf->inferior->pid).release ();
    482 }
    483 
    484 static PyObject *
    485 infpy_get_was_attached (PyObject *self, void *closure)
    486 {
    487   inferior_object *inf = (inferior_object *) self;
    488 
    489   INFPY_REQUIRE_VALID (inf);
    490   if (inf->inferior->attach_flag)
    491     Py_RETURN_TRUE;
    492   Py_RETURN_FALSE;
    493 }
    494 
    495 /* Getter of gdb.Inferior.progspace.  */
    496 
    497 static PyObject *
    498 infpy_get_progspace (PyObject *self, void *closure)
    499 {
    500   inferior_object *inf = (inferior_object *) self;
    501 
    502   INFPY_REQUIRE_VALID (inf);
    503 
    504   program_space *pspace = inf->inferior->pspace;
    505   gdb_assert (pspace != nullptr);
    506 
    507   return pspace_to_pspace_object (pspace).release ();
    508 }
    509 
    510 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
    511    Returns a tuple of all inferiors.  */
    512 PyObject *
    513 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
    514 {
    515   gdbpy_ref<> list (PyList_New (0));
    516   if (list == NULL)
    517     return NULL;
    518 
    519   for (inferior *inf : all_inferiors ())
    520     {
    521       gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
    522 
    523       if (inferior == NULL)
    524 	continue;
    525 
    526       if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
    527 	return NULL;
    528     }
    529 
    530   return PyList_AsTuple (list.get ());
    531 }
    532 
    533 /* Membuf and memory manipulation.  */
    534 
    535 /* Implementation of Inferior.read_memory (address, length).
    536    Returns a Python buffer object with LENGTH bytes of the inferior's
    537    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
    538    with a python exception set.  */
    539 static PyObject *
    540 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
    541 {
    542   inferior_object *inf = (inferior_object *) self;
    543   CORE_ADDR addr, length;
    544   gdb::unique_xmalloc_ptr<gdb_byte> buffer;
    545   PyObject *addr_obj, *length_obj;
    546   static const char *keywords[] = { "address", "length", NULL };
    547 
    548   INFPY_REQUIRE_VALID (inf);
    549 
    550   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
    551 					&addr_obj, &length_obj))
    552     return NULL;
    553 
    554   if (get_addr_from_python (addr_obj, &addr) < 0
    555       || get_addr_from_python (length_obj, &length) < 0)
    556     return NULL;
    557 
    558   if (length == 0)
    559     {
    560       PyErr_SetString (PyExc_ValueError,
    561 		       _("Argument 'count' should be greater than zero"));
    562       return NULL;
    563     }
    564 
    565   void *p = malloc (length);
    566   if (p == nullptr)
    567     return PyErr_NoMemory ();
    568   buffer.reset ((gdb_byte *) p);
    569 
    570   try
    571     {
    572       /* Use this scoped-restore because we want to be able to read
    573 	 memory from an unwinder.  */
    574       scoped_restore_current_inferior_for_memory restore_inferior
    575 	(inf->inferior);
    576 
    577       read_memory (addr, buffer.get (), length);
    578     }
    579   catch (const gdb_exception &except)
    580     {
    581       return gdbpy_handle_gdb_exception (nullptr, except);
    582     }
    583 
    584 
    585   return gdbpy_buffer_to_membuf (std::move (buffer), addr, length);
    586 }
    587 
    588 /* Implementation of Inferior.write_memory (address, buffer [, length]).
    589    Writes the contents of BUFFER (a Python object supporting the read
    590    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
    591    bytes from BUFFER, or its entire contents if the argument is not
    592    provided.  The function returns nothing.  Returns NULL on error, with
    593    a python exception set.  */
    594 static PyObject *
    595 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
    596 {
    597   inferior_object *inf = (inferior_object *) self;
    598   Py_ssize_t buf_len;
    599   const gdb_byte *buffer;
    600   CORE_ADDR addr, length;
    601   PyObject *addr_obj, *length_obj = NULL;
    602   static const char *keywords[] = { "address", "buffer", "length", NULL };
    603   Py_buffer pybuf;
    604 
    605   INFPY_REQUIRE_VALID (inf);
    606 
    607   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
    608 					&addr_obj, &pybuf, &length_obj))
    609     return NULL;
    610 
    611   Py_buffer_up buffer_up (&pybuf);
    612   buffer = (const gdb_byte *) pybuf.buf;
    613   buf_len = pybuf.len;
    614 
    615   if (get_addr_from_python (addr_obj, &addr) < 0)
    616     return nullptr;
    617 
    618   if (!length_obj)
    619     length = buf_len;
    620   else if (get_addr_from_python (length_obj, &length) < 0)
    621     return nullptr;
    622 
    623   try
    624     {
    625       /* It's probably not too important to avoid invalidating the
    626 	 frame cache when writing memory, but this scoped-restore is
    627 	 still used here, just to keep the code similar to other code
    628 	 in this file.  */
    629       scoped_restore_current_inferior_for_memory restore_inferior
    630 	(inf->inferior);
    631 
    632       write_memory_with_notification (addr, buffer, length);
    633     }
    634   catch (const gdb_exception &ex)
    635     {
    636       return gdbpy_handle_gdb_exception (nullptr, ex);
    637     }
    638 
    639   Py_RETURN_NONE;
    640 }
    641 
    642 /* Implementation of
    643    Inferior.search_memory (address, length, pattern).  ADDRESS is the
    644    address to start the search.  LENGTH specifies the scope of the
    645    search from ADDRESS.  PATTERN is the pattern to search for (and
    646    must be a Python object supporting the buffer protocol).
    647    Returns a Python Long object holding the address where the pattern
    648    was located, or if the pattern was not found, returns None.  Returns NULL
    649    on error, with a python exception set.  */
    650 static PyObject *
    651 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
    652 {
    653   inferior_object *inf = (inferior_object *) self;
    654   CORE_ADDR start_addr, length;
    655   static const char *keywords[] = { "address", "length", "pattern", NULL };
    656   PyObject *start_addr_obj, *length_obj;
    657   Py_ssize_t pattern_size;
    658   const gdb_byte *buffer;
    659   CORE_ADDR found_addr;
    660   int found = 0;
    661   Py_buffer pybuf;
    662 
    663   INFPY_REQUIRE_VALID (inf);
    664 
    665   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
    666 					&start_addr_obj, &length_obj,
    667 					&pybuf))
    668     return NULL;
    669 
    670   Py_buffer_up buffer_up (&pybuf);
    671   buffer = (const gdb_byte *) pybuf.buf;
    672   pattern_size = pybuf.len;
    673 
    674   if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
    675     return nullptr;
    676 
    677   if (get_addr_from_python (length_obj, &length) < 0)
    678     return nullptr;
    679 
    680   if (!length)
    681     {
    682       PyErr_SetString (PyExc_ValueError,
    683 		       _("Search range is empty."));
    684       return nullptr;
    685     }
    686   /* Watch for overflows.  */
    687   else if (length > CORE_ADDR_MAX
    688 	   || (start_addr + length - 1) < start_addr)
    689     {
    690       PyErr_SetString (PyExc_ValueError,
    691 		       _("The search range is too large."));
    692       return nullptr;
    693     }
    694 
    695   try
    696     {
    697       /* It's probably not too important to avoid invalidating the
    698 	 frame cache when searching memory, but this scoped-restore is
    699 	 still used here, just to keep the code similar to other code
    700 	 in this file.  */
    701       scoped_restore_current_inferior_for_memory restore_inferior
    702 	(inf->inferior);
    703 
    704       found = target_search_memory (start_addr, length,
    705 				    buffer, pattern_size,
    706 				    &found_addr);
    707     }
    708   catch (const gdb_exception &ex)
    709     {
    710       return gdbpy_handle_gdb_exception (nullptr, ex);
    711     }
    712 
    713   if (found)
    714     return gdb_py_object_from_ulongest (found_addr).release ();
    715   else
    716     Py_RETURN_NONE;
    717 }
    718 
    719 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
    720    Returns True if this inferior object still exists in GDB.  */
    721 
    722 static PyObject *
    723 infpy_is_valid (PyObject *self, PyObject *args)
    724 {
    725   inferior_object *inf = (inferior_object *) self;
    726 
    727   if (! inf->inferior)
    728     Py_RETURN_FALSE;
    729 
    730   Py_RETURN_TRUE;
    731 }
    732 
    733 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
    734 			->  gdb.InferiorThread.  */
    735 
    736 static PyObject *
    737 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
    738 {
    739   PyObject *handle_obj;
    740   inferior_object *inf_obj = (inferior_object *) self;
    741   static const char *keywords[] = { "handle", NULL };
    742 
    743   INFPY_REQUIRE_VALID (inf_obj);
    744 
    745   if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
    746     return NULL;
    747 
    748   const gdb_byte *bytes;
    749   size_t bytes_len;
    750   Py_buffer_up buffer_up;
    751   Py_buffer py_buf;
    752 
    753   if (PyObject_CheckBuffer (handle_obj)
    754       && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
    755     {
    756       buffer_up.reset (&py_buf);
    757       bytes = (const gdb_byte *) py_buf.buf;
    758       bytes_len = py_buf.len;
    759     }
    760   else if (gdbpy_is_value_object (handle_obj))
    761     {
    762       struct value *val = value_object_to_value (handle_obj);
    763       bytes = val->contents_all ().data ();
    764       bytes_len = val->type ()->length ();
    765     }
    766   else
    767     {
    768       PyErr_SetString (PyExc_TypeError,
    769 		       _("Argument 'handle' must be a thread handle object."));
    770 
    771       return NULL;
    772     }
    773 
    774   try
    775     {
    776       struct thread_info *thread_info;
    777 
    778       thread_info = find_thread_by_handle
    779 	(gdb::array_view<const gdb_byte> (bytes, bytes_len),
    780 	 inf_obj->inferior);
    781       if (thread_info != NULL)
    782 	return thread_to_thread_object (thread_info).release ();
    783     }
    784   catch (const gdb_exception &except)
    785     {
    786       return gdbpy_handle_gdb_exception (nullptr, except);
    787     }
    788 
    789   Py_RETURN_NONE;
    790 }
    791 
    792 /* Implementation of gdb.Inferior.architecture.  */
    793 
    794 static PyObject *
    795 infpy_architecture (PyObject *self, PyObject *args)
    796 {
    797   inferior_object *inf = (inferior_object *) self;
    798 
    799   INFPY_REQUIRE_VALID (inf);
    800 
    801   return gdbarch_to_arch_object (inf->inferior->arch ());
    802 }
    803 
    804 /* Implement repr() for gdb.Inferior.  */
    805 
    806 static PyObject *
    807 infpy_repr (PyObject *obj)
    808 {
    809   inferior_object *self = (inferior_object *) obj;
    810   inferior *inf = self->inferior;
    811 
    812   if (inf == nullptr)
    813     return gdb_py_invalid_object_repr (obj);
    814 
    815   return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
    816 			       inf->num, inf->pid);
    817 }
    818 
    819 /* Implement clear_env.  */
    820 
    821 static PyObject *
    822 infpy_clear_env (PyObject *obj)
    823 {
    824   inferior_object *self = (inferior_object *) obj;
    825 
    826   INFPY_REQUIRE_VALID (self);
    827 
    828   self->inferior->environment.clear ();
    829   Py_RETURN_NONE;
    830 }
    831 
    832 /* Implement set_env.  */
    833 
    834 static PyObject *
    835 infpy_set_env (PyObject *obj, PyObject *args, PyObject *kw)
    836 {
    837   inferior_object *self = (inferior_object *) obj;
    838   INFPY_REQUIRE_VALID (self);
    839 
    840   const char *name, *val;
    841   static const char *keywords[] = { "name", "value", nullptr };
    842 
    843   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "ss", keywords,
    844 					&name, &val))
    845     return nullptr;
    846 
    847   self->inferior->environment.set (name, val);
    848   Py_RETURN_NONE;
    849 }
    850 
    851 /* Implement unset_env.  */
    852 
    853 static PyObject *
    854 infpy_unset_env (PyObject *obj, PyObject *args, PyObject *kw)
    855 {
    856   inferior_object *self = (inferior_object *) obj;
    857   INFPY_REQUIRE_VALID (self);
    858 
    859   const char *name;
    860   static const char *keywords[] = { "name", nullptr };
    861   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &name))
    862     return nullptr;
    863 
    864   self->inferior->environment.unset (name);
    865   Py_RETURN_NONE;
    866 }
    867 
    868 /* Getter for "arguments".  */
    869 
    870 static PyObject *
    871 infpy_get_args (PyObject *self, void *closure)
    872 {
    873   inferior_object *inf = (inferior_object *) self;
    874 
    875   INFPY_REQUIRE_VALID (inf);
    876 
    877   const std::string &args = inf->inferior->args ();
    878   if (args.empty ())
    879     Py_RETURN_NONE;
    880 
    881   return host_string_to_python_string (args.c_str ()).release ();
    882 }
    883 
    884 /* Setter for "arguments".  */
    885 
    886 static int
    887 infpy_set_args (PyObject *self, PyObject *value, void *closure)
    888 {
    889   inferior_object *inf = (inferior_object *) self;
    890 
    891   if (!inf->inferior)
    892     {
    893       PyErr_SetString (PyExc_RuntimeError, _("Inferior no longer exists."));
    894       return -1;
    895     }
    896 
    897   if (value == nullptr)
    898     {
    899       PyErr_SetString (PyExc_TypeError,
    900 		       _("Cannot delete 'arguments' attribute."));
    901       return -1;
    902     }
    903 
    904   if (gdbpy_is_string (value))
    905     {
    906       gdb::unique_xmalloc_ptr<char> str = python_string_to_host_string (value);
    907       if (str == nullptr)
    908 	return -1;
    909       inf->inferior->set_args (std::string (str.get ()));
    910     }
    911   else if (PySequence_Check (value))
    912     {
    913       std::vector<gdb::unique_xmalloc_ptr<char>> args;
    914       Py_ssize_t len = PySequence_Size (value);
    915       if (len == -1)
    916 	return -1;
    917       for (Py_ssize_t i = 0; i < len; ++i)
    918 	{
    919 	  gdbpy_ref<> item (PySequence_ITEM (value, i));
    920 	  if (item == nullptr)
    921 	    return -1;
    922 	  gdb::unique_xmalloc_ptr<char> str
    923 	    = python_string_to_host_string (item.get ());
    924 	  if (str == nullptr)
    925 	    return -1;
    926 	  args.push_back (std::move (str));
    927 	}
    928       std::vector<char *> argvec;
    929       for (const auto &arg : args)
    930 	argvec.push_back (arg.get ());
    931       gdb::array_view<char * const> view (argvec.data (), argvec.size ());
    932       inf->inferior->set_args (view);
    933     }
    934   else
    935     {
    936       PyErr_SetString (PyExc_TypeError,
    937 		       _("string or sequence required for 'arguments'"));
    938       return -1;
    939     }
    940   return 0;
    941 }
    942 
    943 /* Getter for "main_name".  */
    944 
    945 static PyObject *
    946 infpy_get_main_name (PyObject *self, void *closure)
    947 {
    948   inferior_object *inf = (inferior_object *) self;
    949 
    950   INFPY_REQUIRE_VALID (inf);
    951 
    952   const char *name = nullptr;
    953   try
    954     {
    955       /* This is unfortunate but the implementation of main_name can
    956 	 reach into memory.  It's probably not too important to avoid
    957 	 invalidating the frame cache here, but this scoped-restore is
    958 	 still used, just to keep the code similar to other code in
    959 	 this file.  */
    960       scoped_restore_current_inferior_for_memory restore_inferior
    961 	(inf->inferior);
    962 
    963       name = main_name ();
    964     }
    965   catch (const gdb_exception &except)
    966     {
    967       /* We can just ignore this.  */
    968     }
    969 
    970   if (name == nullptr)
    971     Py_RETURN_NONE;
    972 
    973   return host_string_to_python_string (name).release ();
    974 }
    975 
    976 static void
    977 infpy_dealloc (PyObject *obj)
    978 {
    979   inferior_object *inf_obj = (inferior_object *) obj;
    980 
    981   /* The inferior itself holds a reference to this Python object, which
    982      will keep the reference count of this object above zero until GDB
    983      deletes the inferior and py_free_inferior is called.
    984 
    985      Once py_free_inferior has been called then the link between this
    986      Python object and the inferior is set to nullptr, and then the
    987      reference count on this Python object is decremented.
    988 
    989      The result of all this is that the link between this Python object and
    990      the inferior should always have been set to nullptr before this
    991      function is called.  */
    992   gdb_assert (inf_obj->inferior == nullptr);
    993 
    994   Py_XDECREF (inf_obj->dict);
    995 
    996   Py_TYPE (obj)->tp_free (obj);
    997 }
    998 
    999 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
   1000    Returns the current inferior object.  */
   1001 
   1002 PyObject *
   1003 gdbpy_selected_inferior (PyObject *self, PyObject *args)
   1004 {
   1005   return ((PyObject *)
   1006 	  inferior_to_inferior_object (current_inferior ()).release ());
   1007 }
   1008 
   1009 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
   1010 gdbpy_initialize_inferior (void)
   1011 {
   1012   if (gdbpy_type_ready (&inferior_object_type) < 0)
   1013     return -1;
   1014 
   1015   gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
   1016   gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
   1017   gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
   1018   gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
   1019   gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
   1020 					    "py-inferior");
   1021   gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
   1022 					     "py-inferior");
   1023   gdb::observers::memory_changed.attach (python_on_memory_change,
   1024 					 "py-inferior");
   1025   gdb::observers::register_changed.attach (python_on_register_change,
   1026 					   "py-inferior");
   1027   gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
   1028   /* Need to run after auto-load's new_objfile observer, so that
   1029      auto-loaded pretty-printers are available.  */
   1030   gdb::observers::new_objfile.attach
   1031     (python_new_objfile, "py-inferior",
   1032      { &auto_load_new_objfile_observer_token });
   1033   gdb::observers::all_objfiles_removed.attach (python_all_objfiles_removed,
   1034 					       "py-inferior");
   1035   gdb::observers::free_objfile.attach (python_free_objfile, "py-inferior");
   1036   gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
   1037   gdb::observers::inferior_removed.attach (python_inferior_deleted,
   1038 					   "py-inferior");
   1039 
   1040   return 0;
   1041 }
   1042 
   1043 GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior);
   1044 
   1045 
   1046 
   1048 static gdb_PyGetSetDef inferior_object_getset[] =
   1049 {
   1050   { "__dict__", gdb_py_generic_dict, nullptr,
   1051     "The __dict__ for this inferior.", &inferior_object_type },
   1052   { "arguments", infpy_get_args, infpy_set_args,
   1053     "Arguments to this program.", nullptr },
   1054   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
   1055   { "connection", infpy_get_connection, NULL,
   1056     "The gdb.TargetConnection for this inferior.", NULL },
   1057   { "connection_num", infpy_get_connection_num, NULL,
   1058     "ID of inferior's connection, as assigned by GDB.", NULL },
   1059   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
   1060     NULL },
   1061   { "was_attached", infpy_get_was_attached, NULL,
   1062     "True if the inferior was created using 'attach'.", NULL },
   1063   { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
   1064   { "main_name", infpy_get_main_name, nullptr,
   1065     "Name of 'main' function, if known.", nullptr },
   1066   { NULL }
   1067 };
   1068 
   1069 static PyMethodDef inferior_object_methods[] =
   1070 {
   1071   { "is_valid", infpy_is_valid, METH_NOARGS,
   1072     "is_valid () -> Boolean.\n\
   1073 Return true if this inferior is valid, false if not." },
   1074   { "threads", infpy_threads, METH_NOARGS,
   1075     "Return all the threads of this inferior." },
   1076   { "read_memory", (PyCFunction) infpy_read_memory,
   1077     METH_VARARGS | METH_KEYWORDS,
   1078     "read_memory (address, length) -> buffer\n\
   1079 Return a buffer object for reading from the inferior's memory." },
   1080   { "write_memory", (PyCFunction) infpy_write_memory,
   1081     METH_VARARGS | METH_KEYWORDS,
   1082     "write_memory (address, buffer [, length])\n\
   1083 Write the given buffer object to the inferior's memory." },
   1084   { "search_memory", (PyCFunction) infpy_search_memory,
   1085     METH_VARARGS | METH_KEYWORDS,
   1086     "search_memory (address, length, pattern) -> long\n\
   1087 Return a long with the address of a match, or None." },
   1088   /* thread_from_thread_handle is deprecated.  */
   1089   { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
   1090     METH_VARARGS | METH_KEYWORDS,
   1091     "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
   1092 Return thread object corresponding to thread handle.\n\
   1093 This method is deprecated - use thread_from_handle instead." },
   1094   { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
   1095     METH_VARARGS | METH_KEYWORDS,
   1096     "thread_from_handle (handle) -> gdb.InferiorThread.\n\
   1097 Return thread object corresponding to thread handle." },
   1098   { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
   1099     "architecture () -> gdb.Architecture\n\
   1100 Return architecture of this inferior." },
   1101   { "clear_env", (PyCFunction) infpy_clear_env, METH_NOARGS,
   1102     "clear_env () -> None\n\
   1103 Clear environment of this inferior." },
   1104   { "set_env", (PyCFunction) infpy_set_env, METH_VARARGS | METH_KEYWORDS,
   1105     "set_env (name, value) -> None\n\
   1106 Set an environment variable of this inferior." },
   1107   { "unset_env", (PyCFunction) infpy_unset_env, METH_VARARGS | METH_KEYWORDS,
   1108     "unset_env (name) -> None\n\
   1109 Unset an environment of this inferior." },
   1110   { NULL }
   1111 };
   1112 
   1113 PyTypeObject inferior_object_type =
   1114 {
   1115   PyVarObject_HEAD_INIT (NULL, 0)
   1116   "gdb.Inferior",		  /* tp_name */
   1117   sizeof (inferior_object),	  /* tp_basicsize */
   1118   0,				  /* tp_itemsize */
   1119   infpy_dealloc,		  /* tp_dealloc */
   1120   0,				  /* tp_print */
   1121   0,				  /* tp_getattr */
   1122   0,				  /* tp_setattr */
   1123   0,				  /* tp_compare */
   1124   infpy_repr,			  /* tp_repr */
   1125   0,				  /* tp_as_number */
   1126   0,				  /* tp_as_sequence */
   1127   0,				  /* tp_as_mapping */
   1128   0,				  /* tp_hash  */
   1129   0,				  /* tp_call */
   1130   0,				  /* tp_str */
   1131   0,				  /* tp_getattro */
   1132   0,				  /* tp_setattro */
   1133   0,				  /* tp_as_buffer */
   1134   Py_TPFLAGS_DEFAULT,		  /* tp_flags */
   1135   "GDB inferior object",	  /* tp_doc */
   1136   0,				  /* tp_traverse */
   1137   0,				  /* tp_clear */
   1138   0,				  /* tp_richcompare */
   1139   0,				  /* tp_weaklistoffset */
   1140   0,				  /* tp_iter */
   1141   0,				  /* tp_iternext */
   1142   inferior_object_methods,	  /* tp_methods */
   1143   0,				  /* tp_members */
   1144   inferior_object_getset,	  /* tp_getset */
   1145   0,				  /* tp_base */
   1146   0,				  /* tp_dict */
   1147   0,				  /* tp_descr_get */
   1148   0,				  /* tp_descr_set */
   1149   offsetof (inferior_object, dict), /* tp_dictoffset */
   1150   0,				  /* tp_init */
   1151   0				  /* tp_alloc */
   1152 };
   1153