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