xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/python/py-inferior.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Python interface to inferiors.
2 
3    Copyright (C) 2009-2023 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "auto-load.h"
22 #include "gdbcore.h"
23 #include "gdbthread.h"
24 #include "inferior.h"
25 #include "objfiles.h"
26 #include "observable.h"
27 #include "python-internal.h"
28 #include "arch-utils.h"
29 #include "language.h"
30 #include "gdbsupport/gdb_signals.h"
31 #include "py-event.h"
32 #include "py-stopevent.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 
50 extern PyTypeObject inferior_object_type
51     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
52 
53 /* Deleter to clean up when an inferior is removed.  */
54 struct infpy_deleter
55 {
56   void operator() (inferior_object *obj)
57   {
58     if (!gdb_python_initialized)
59       return;
60 
61     gdbpy_enter enter_py;
62     gdbpy_ref<inferior_object> inf_obj (obj);
63 
64     inf_obj->inferior = NULL;
65 
66     delete inf_obj->threads;
67   }
68 };
69 
70 static const registry<inferior>::key<inferior_object, infpy_deleter>
71      infpy_inf_data_key;
72 
73 /* Require that INFERIOR be a valid inferior ID.  */
74 #define INFPY_REQUIRE_VALID(Inferior)				\
75   do {								\
76     if (!Inferior->inferior)					\
77       {								\
78 	PyErr_SetString (PyExc_RuntimeError,			\
79 			 _("Inferior no longer exists."));	\
80 	return NULL;						\
81       }								\
82   } while (0)
83 
84 static void
85 python_on_normal_stop (struct bpstat *bs, int print_frame)
86 {
87   enum gdb_signal stop_signal;
88 
89   if (!gdb_python_initialized)
90     return;
91 
92   if (inferior_ptid == null_ptid)
93     return;
94 
95   stop_signal = inferior_thread ()->stop_signal ();
96 
97   gdbpy_enter enter_py;
98 
99   if (emit_stop_event (bs, stop_signal) < 0)
100     gdbpy_print_stack ();
101 }
102 
103 static void
104 python_on_resume (ptid_t ptid)
105 {
106   if (!gdb_python_initialized)
107     return;
108 
109   gdbpy_enter enter_py (target_gdbarch ());
110 
111   if (emit_continue_event (ptid) < 0)
112     gdbpy_print_stack ();
113 }
114 
115 /* Callback, registered as an observer, that notifies Python listeners
116    when an inferior function call is about to be made. */
117 
118 static void
119 python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
120 {
121   gdbpy_enter enter_py (target_gdbarch ());
122 
123   if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
124     gdbpy_print_stack ();
125 }
126 
127 /* Callback, registered as an observer, that notifies Python listeners
128    when an inferior function call has completed. */
129 
130 static void
131 python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
132 {
133   gdbpy_enter enter_py (target_gdbarch ());
134 
135   if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
136     gdbpy_print_stack ();
137 }
138 
139 /* Callback, registered as an observer, that notifies Python listeners
140    when a part of memory has been modified by user action (eg via a
141    'set' command). */
142 
143 static void
144 python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
145 {
146   gdbpy_enter enter_py (target_gdbarch ());
147 
148   if (emit_memory_changed_event (addr, len) < 0)
149     gdbpy_print_stack ();
150 }
151 
152 /* Callback, registered as an observer, that notifies Python listeners
153    when a register has been modified by user action (eg via a 'set'
154    command). */
155 
156 static void
157 python_on_register_change (frame_info_ptr frame, int regnum)
158 {
159   gdbpy_enter enter_py (target_gdbarch ());
160 
161   if (emit_register_changed_event (frame, regnum) < 0)
162     gdbpy_print_stack ();
163 }
164 
165 static void
166 python_inferior_exit (struct inferior *inf)
167 {
168   const LONGEST *exit_code = NULL;
169 
170   if (!gdb_python_initialized)
171     return;
172 
173   gdbpy_enter enter_py (target_gdbarch ());
174 
175   if (inf->has_exit_code)
176     exit_code = &inf->exit_code;
177 
178   if (emit_exited_event (exit_code, inf) < 0)
179     gdbpy_print_stack ();
180 }
181 
182 /* Callback used to notify Python listeners about new objfiles loaded in the
183    inferior.  OBJFILE may be NULL which means that the objfile list has been
184    cleared (emptied).  */
185 
186 static void
187 python_new_objfile (struct objfile *objfile)
188 {
189   if (!gdb_python_initialized)
190     return;
191 
192   gdbpy_enter enter_py (objfile != NULL
193 			? objfile->arch ()
194 			: target_gdbarch ());
195 
196   if (objfile == NULL)
197     {
198       if (emit_clear_objfiles_event () < 0)
199 	gdbpy_print_stack ();
200     }
201   else
202     {
203       if (emit_new_objfile_event (objfile) < 0)
204 	gdbpy_print_stack ();
205     }
206 }
207 
208 /* Emit a Python event when an objfile is about to be removed.  */
209 
210 static void
211 python_free_objfile (struct objfile *objfile)
212 {
213   if (!gdb_python_initialized)
214     return;
215 
216   gdbpy_enter enter_py (objfile->arch ());
217 
218   if (emit_free_objfile_event (objfile) < 0)
219     gdbpy_print_stack ();
220 }
221 
222 /* Return a reference to the Python object of type Inferior
223    representing INFERIOR.  If the object has already been created,
224    return it and increment the reference count,  otherwise, create it.
225    Return NULL on failure.  */
226 
227 gdbpy_ref<inferior_object>
228 inferior_to_inferior_object (struct inferior *inferior)
229 {
230   inferior_object *inf_obj;
231 
232   inf_obj = infpy_inf_data_key.get (inferior);
233   if (!inf_obj)
234     {
235       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
236       if (!inf_obj)
237 	return NULL;
238 
239       inf_obj->inferior = inferior;
240       inf_obj->threads = new thread_map_t ();
241 
242       /* PyObject_New initializes the new object with a refcount of 1.  This
243 	 counts for the reference we are keeping in the inferior data.  */
244       infpy_inf_data_key.set (inferior, inf_obj);
245     }
246 
247   /* We are returning a new reference.  */
248   gdb_assert (inf_obj != nullptr);
249   return gdbpy_ref<inferior_object>::new_reference (inf_obj);
250 }
251 
252 /* Called when a new inferior is created.  Notifies any Python event
253    listeners.  */
254 static void
255 python_new_inferior (struct inferior *inf)
256 {
257   if (!gdb_python_initialized)
258     return;
259 
260   gdbpy_enter enter_py;
261 
262   if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
263     return;
264 
265   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
266   if (inf_obj == NULL)
267     {
268       gdbpy_print_stack ();
269       return;
270     }
271 
272   gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
273   if (event == NULL
274       || evpy_add_attribute (event.get (), "inferior",
275 			     (PyObject *) inf_obj.get ()) < 0
276       || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
277     gdbpy_print_stack ();
278 }
279 
280 /* Called when an inferior is removed.  Notifies any Python event
281    listeners.  */
282 static void
283 python_inferior_deleted (struct inferior *inf)
284 {
285   if (!gdb_python_initialized)
286     return;
287 
288   gdbpy_enter enter_py;
289 
290   if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
291     return;
292 
293   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
294   if (inf_obj == NULL)
295     {
296       gdbpy_print_stack ();
297       return;
298     }
299 
300   gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
301   if (event == NULL
302       || evpy_add_attribute (event.get (), "inferior",
303 			     (PyObject *) inf_obj.get ()) < 0
304       || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
305     gdbpy_print_stack ();
306 }
307 
308 gdbpy_ref<>
309 thread_to_thread_object (thread_info *thr)
310 {
311   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
312   if (inf_obj == NULL)
313     return NULL;
314 
315   auto thread_it = inf_obj->threads->find (thr);
316   if (thread_it != inf_obj->threads->end ())
317     return gdbpy_ref<>::new_reference
318       ((PyObject *) (thread_it->second.get ()));
319 
320   PyErr_SetString (PyExc_SystemError,
321 		   _("could not find gdb thread object"));
322   return NULL;
323 }
324 
325 static void
326 add_thread_object (struct thread_info *tp)
327 {
328   inferior_object *inf_obj;
329 
330   if (!gdb_python_initialized)
331     return;
332 
333   gdbpy_enter enter_py;
334 
335   gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
336   if (thread_obj == NULL)
337     {
338       gdbpy_print_stack ();
339       return;
340     }
341 
342   inf_obj = (inferior_object *) thread_obj->inf_obj;
343 
344   auto ins_result = inf_obj->threads->emplace
345     (thread_map_t::value_type (tp, std::move (thread_obj)));
346 
347   if (!ins_result.second)
348     return;
349 
350   if (evregpy_no_listeners_p (gdb_py_events.new_thread))
351     return;
352 
353   gdbpy_ref<> event = create_thread_event_object
354     (&new_thread_event_object_type,
355      (PyObject *) ins_result.first->second.get ());
356 
357   if (event == NULL
358       || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
359     gdbpy_print_stack ();
360 }
361 
362 static void
363 delete_thread_object (struct thread_info *tp, int ignore)
364 {
365   if (!gdb_python_initialized)
366     return;
367 
368   gdbpy_enter enter_py;
369 
370   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
371   if (inf_obj == NULL)
372     return;
373 
374   auto it = inf_obj->threads->find (tp);
375   if (it != inf_obj->threads->end ())
376     {
377       /* Some python code can still hold a reference to the thread_object
378 	 instance.   Make sure to remove the link to the associated
379 	 thread_info object as it will be freed soon.  This makes the python
380 	 object invalid (i.e. gdb.InfThread.is_valid returns False).  */
381       it->second->thread = nullptr;
382       inf_obj->threads->erase (it);
383     }
384 }
385 
386 static PyObject *
387 infpy_threads (PyObject *self, PyObject *args)
388 {
389   int i = 0;
390   inferior_object *inf_obj = (inferior_object *) self;
391   PyObject *tuple;
392 
393   INFPY_REQUIRE_VALID (inf_obj);
394 
395   try
396     {
397       update_thread_list ();
398     }
399   catch (const gdb_exception &except)
400     {
401       GDB_PY_HANDLE_EXCEPTION (except);
402     }
403 
404   tuple = PyTuple_New (inf_obj->threads->size ());
405   if (!tuple)
406     return NULL;
407 
408   for (const thread_map_t::value_type &entry : *inf_obj->threads)
409     {
410       PyObject *thr = (PyObject *) entry.second.get ();
411       Py_INCREF (thr);
412       PyTuple_SET_ITEM (tuple, i, thr);
413       i = i + 1;
414     }
415 
416   return tuple;
417 }
418 
419 static PyObject *
420 infpy_get_num (PyObject *self, void *closure)
421 {
422   inferior_object *inf = (inferior_object *) self;
423 
424   INFPY_REQUIRE_VALID (inf);
425 
426   return gdb_py_object_from_longest (inf->inferior->num).release ();
427 }
428 
429 /* Return the gdb.TargetConnection object for this inferior, or None if a
430    connection does not exist.  */
431 
432 static PyObject *
433 infpy_get_connection (PyObject *self, void *closure)
434 {
435   inferior_object *inf = (inferior_object *) self;
436 
437   INFPY_REQUIRE_VALID (inf);
438 
439   process_stratum_target *target = inf->inferior->process_target ();
440   return target_to_connection_object (target).release ();
441 }
442 
443 /* Return the connection number of the given inferior, or None if a
444    connection does not exist.  */
445 
446 static PyObject *
447 infpy_get_connection_num (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   if (target == nullptr)
455     Py_RETURN_NONE;
456 
457   return gdb_py_object_from_longest (target->connection_number).release ();
458 }
459 
460 static PyObject *
461 infpy_get_pid (PyObject *self, void *closure)
462 {
463   inferior_object *inf = (inferior_object *) self;
464 
465   INFPY_REQUIRE_VALID (inf);
466 
467   return gdb_py_object_from_longest (inf->inferior->pid).release ();
468 }
469 
470 static PyObject *
471 infpy_get_was_attached (PyObject *self, void *closure)
472 {
473   inferior_object *inf = (inferior_object *) self;
474 
475   INFPY_REQUIRE_VALID (inf);
476   if (inf->inferior->attach_flag)
477     Py_RETURN_TRUE;
478   Py_RETURN_FALSE;
479 }
480 
481 /* Getter of gdb.Inferior.progspace.  */
482 
483 static PyObject *
484 infpy_get_progspace (PyObject *self, void *closure)
485 {
486   inferior_object *inf = (inferior_object *) self;
487 
488   INFPY_REQUIRE_VALID (inf);
489 
490   program_space *pspace = inf->inferior->pspace;
491   gdb_assert (pspace != nullptr);
492 
493   return pspace_to_pspace_object (pspace).release ();
494 }
495 
496 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
497    Returns a tuple of all inferiors.  */
498 PyObject *
499 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
500 {
501   gdbpy_ref<> list (PyList_New (0));
502   if (list == NULL)
503     return NULL;
504 
505   for (inferior *inf : all_inferiors ())
506     {
507       gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
508 
509       if (inferior == NULL)
510 	continue;
511 
512       if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
513 	return NULL;
514     }
515 
516   return PyList_AsTuple (list.get ());
517 }
518 
519 /* Membuf and memory manipulation.  */
520 
521 /* Implementation of Inferior.read_memory (address, length).
522    Returns a Python buffer object with LENGTH bytes of the inferior's
523    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
524    with a python exception set.  */
525 static PyObject *
526 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
527 {
528   CORE_ADDR addr, length;
529   gdb::unique_xmalloc_ptr<gdb_byte> buffer;
530   PyObject *addr_obj, *length_obj;
531   static const char *keywords[] = { "address", "length", NULL };
532 
533   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
534 					&addr_obj, &length_obj))
535     return NULL;
536 
537   if (get_addr_from_python (addr_obj, &addr) < 0
538       || get_addr_from_python (length_obj, &length) < 0)
539     return NULL;
540 
541   try
542     {
543       buffer.reset ((gdb_byte *) xmalloc (length));
544 
545       read_memory (addr, buffer.get (), length);
546     }
547   catch (const gdb_exception &except)
548     {
549       GDB_PY_HANDLE_EXCEPTION (except);
550     }
551 
552 
553   return gdbpy_buffer_to_membuf (std::move (buffer), addr, length);
554 }
555 
556 /* Implementation of Inferior.write_memory (address, buffer [, length]).
557    Writes the contents of BUFFER (a Python object supporting the read
558    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
559    bytes from BUFFER, or its entire contents if the argument is not
560    provided.  The function returns nothing.  Returns NULL on error, with
561    a python exception set.  */
562 static PyObject *
563 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
564 {
565   struct gdb_exception except;
566   Py_ssize_t buf_len;
567   const gdb_byte *buffer;
568   CORE_ADDR addr, length;
569   PyObject *addr_obj, *length_obj = NULL;
570   static const char *keywords[] = { "address", "buffer", "length", NULL };
571   Py_buffer pybuf;
572 
573   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
574 					&addr_obj, &pybuf, &length_obj))
575     return NULL;
576 
577   Py_buffer_up buffer_up (&pybuf);
578   buffer = (const gdb_byte *) pybuf.buf;
579   buf_len = pybuf.len;
580 
581   if (get_addr_from_python (addr_obj, &addr) < 0)
582     return nullptr;
583 
584   if (!length_obj)
585     length = buf_len;
586   else if (get_addr_from_python (length_obj, &length) < 0)
587     return nullptr;
588 
589   try
590     {
591       write_memory_with_notification (addr, buffer, length);
592     }
593   catch (gdb_exception &ex)
594     {
595       except = std::move (ex);
596     }
597 
598   GDB_PY_HANDLE_EXCEPTION (except);
599 
600   Py_RETURN_NONE;
601 }
602 
603 /* Implementation of
604    gdb.search_memory (address, length, pattern).  ADDRESS is the
605    address to start the search.  LENGTH specifies the scope of the
606    search from ADDRESS.  PATTERN is the pattern to search for (and
607    must be a Python object supporting the buffer protocol).
608    Returns a Python Long object holding the address where the pattern
609    was located, or if the pattern was not found, returns None.  Returns NULL
610    on error, with a python exception set.  */
611 static PyObject *
612 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
613 {
614   struct gdb_exception except;
615   CORE_ADDR start_addr, length;
616   static const char *keywords[] = { "address", "length", "pattern", NULL };
617   PyObject *start_addr_obj, *length_obj;
618   Py_ssize_t pattern_size;
619   const gdb_byte *buffer;
620   CORE_ADDR found_addr;
621   int found = 0;
622   Py_buffer pybuf;
623 
624   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
625 					&start_addr_obj, &length_obj,
626 					&pybuf))
627     return NULL;
628 
629   Py_buffer_up buffer_up (&pybuf);
630   buffer = (const gdb_byte *) pybuf.buf;
631   pattern_size = pybuf.len;
632 
633   if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
634     return nullptr;
635 
636   if (get_addr_from_python (length_obj, &length) < 0)
637     return nullptr;
638 
639   if (!length)
640     {
641       PyErr_SetString (PyExc_ValueError,
642 		       _("Search range is empty."));
643       return nullptr;
644     }
645   /* Watch for overflows.  */
646   else if (length > CORE_ADDR_MAX
647 	   || (start_addr + length - 1) < start_addr)
648     {
649       PyErr_SetString (PyExc_ValueError,
650 		       _("The search range is too large."));
651       return nullptr;
652     }
653 
654   try
655     {
656       found = target_search_memory (start_addr, length,
657 				    buffer, pattern_size,
658 				    &found_addr);
659     }
660   catch (gdb_exception &ex)
661     {
662       except = std::move (ex);
663     }
664 
665   GDB_PY_HANDLE_EXCEPTION (except);
666 
667   if (found)
668     return gdb_py_object_from_ulongest (found_addr).release ();
669   else
670     Py_RETURN_NONE;
671 }
672 
673 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
674    Returns True if this inferior object still exists in GDB.  */
675 
676 static PyObject *
677 infpy_is_valid (PyObject *self, PyObject *args)
678 {
679   inferior_object *inf = (inferior_object *) self;
680 
681   if (! inf->inferior)
682     Py_RETURN_FALSE;
683 
684   Py_RETURN_TRUE;
685 }
686 
687 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
688 			->  gdb.InferiorThread.  */
689 
690 static PyObject *
691 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
692 {
693   PyObject *handle_obj;
694   inferior_object *inf_obj = (inferior_object *) self;
695   static const char *keywords[] = { "handle", NULL };
696 
697   INFPY_REQUIRE_VALID (inf_obj);
698 
699   if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
700     return NULL;
701 
702   const gdb_byte *bytes;
703   size_t bytes_len;
704   Py_buffer_up buffer_up;
705   Py_buffer py_buf;
706 
707   if (PyObject_CheckBuffer (handle_obj)
708       && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
709     {
710       buffer_up.reset (&py_buf);
711       bytes = (const gdb_byte *) py_buf.buf;
712       bytes_len = py_buf.len;
713     }
714   else if (gdbpy_is_value_object (handle_obj))
715     {
716       struct value *val = value_object_to_value (handle_obj);
717       bytes = value_contents_all (val).data ();
718       bytes_len = value_type (val)->length ();
719     }
720   else
721     {
722       PyErr_SetString (PyExc_TypeError,
723 		       _("Argument 'handle' must be a thread handle object."));
724 
725       return NULL;
726     }
727 
728   try
729     {
730       struct thread_info *thread_info;
731 
732       thread_info = find_thread_by_handle
733 	(gdb::array_view<const gdb_byte> (bytes, bytes_len),
734 	 inf_obj->inferior);
735       if (thread_info != NULL)
736 	return thread_to_thread_object (thread_info).release ();
737     }
738   catch (const gdb_exception &except)
739     {
740       GDB_PY_HANDLE_EXCEPTION (except);
741     }
742 
743   Py_RETURN_NONE;
744 }
745 
746 /* Implementation of gdb.Inferior.architecture.  */
747 
748 static PyObject *
749 infpy_architecture (PyObject *self, PyObject *args)
750 {
751   inferior_object *inf = (inferior_object *) self;
752 
753   INFPY_REQUIRE_VALID (inf);
754 
755   return gdbarch_to_arch_object (inf->inferior->gdbarch);
756 }
757 
758 /* Implement repr() for gdb.Inferior.  */
759 
760 static PyObject *
761 infpy_repr (PyObject *obj)
762 {
763   inferior_object *self = (inferior_object *) obj;
764   inferior *inf = self->inferior;
765 
766   if (inf == nullptr)
767     return PyUnicode_FromString ("<gdb.Inferior (invalid)>");
768 
769   return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
770 			       inf->num, inf->pid);
771 }
772 
773 
774 static void
775 infpy_dealloc (PyObject *obj)
776 {
777   inferior_object *inf_obj = (inferior_object *) obj;
778 
779   /* The inferior itself holds a reference to this Python object, which
780      will keep the reference count of this object above zero until GDB
781      deletes the inferior and py_free_inferior is called.
782 
783      Once py_free_inferior has been called then the link between this
784      Python object and the inferior is set to nullptr, and then the
785      reference count on this Python object is decremented.
786 
787      The result of all this is that the link between this Python object and
788      the inferior should always have been set to nullptr before this
789      function is called.  */
790   gdb_assert (inf_obj->inferior == nullptr);
791 
792   Py_TYPE (obj)->tp_free (obj);
793 }
794 
795 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
796    Returns the current inferior object.  */
797 
798 PyObject *
799 gdbpy_selected_inferior (PyObject *self, PyObject *args)
800 {
801   return ((PyObject *)
802 	  inferior_to_inferior_object (current_inferior ()).release ());
803 }
804 
805 int
806 gdbpy_initialize_inferior (void)
807 {
808   if (PyType_Ready (&inferior_object_type) < 0)
809     return -1;
810 
811   if (gdb_pymodule_addobject (gdb_module, "Inferior",
812 			      (PyObject *) &inferior_object_type) < 0)
813     return -1;
814 
815   gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
816   gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
817   gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
818   gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
819   gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
820 					    "py-inferior");
821   gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
822 					     "py-inferior");
823   gdb::observers::memory_changed.attach (python_on_memory_change,
824 					 "py-inferior");
825   gdb::observers::register_changed.attach (python_on_register_change,
826 					   "py-inferior");
827   gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
828   /* Need to run after auto-load's new_objfile observer, so that
829      auto-loaded pretty-printers are available.  */
830   gdb::observers::new_objfile.attach
831     (python_new_objfile, "py-inferior",
832      { &auto_load_new_objfile_observer_token });
833   gdb::observers::free_objfile.attach (python_free_objfile, "py-inferior");
834   gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
835   gdb::observers::inferior_removed.attach (python_inferior_deleted,
836 					   "py-inferior");
837 
838   return 0;
839 }
840 
841 static gdb_PyGetSetDef inferior_object_getset[] =
842 {
843   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
844   { "connection", infpy_get_connection, NULL,
845     "The gdb.TargetConnection for this inferior.", NULL },
846   { "connection_num", infpy_get_connection_num, NULL,
847     "ID of inferior's connection, as assigned by GDB.", NULL },
848   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
849     NULL },
850   { "was_attached", infpy_get_was_attached, NULL,
851     "True if the inferior was created using 'attach'.", NULL },
852   { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
853   { NULL }
854 };
855 
856 static PyMethodDef inferior_object_methods[] =
857 {
858   { "is_valid", infpy_is_valid, METH_NOARGS,
859     "is_valid () -> Boolean.\n\
860 Return true if this inferior is valid, false if not." },
861   { "threads", infpy_threads, METH_NOARGS,
862     "Return all the threads of this inferior." },
863   { "read_memory", (PyCFunction) infpy_read_memory,
864     METH_VARARGS | METH_KEYWORDS,
865     "read_memory (address, length) -> buffer\n\
866 Return a buffer object for reading from the inferior's memory." },
867   { "write_memory", (PyCFunction) infpy_write_memory,
868     METH_VARARGS | METH_KEYWORDS,
869     "write_memory (address, buffer [, length])\n\
870 Write the given buffer object to the inferior's memory." },
871   { "search_memory", (PyCFunction) infpy_search_memory,
872     METH_VARARGS | METH_KEYWORDS,
873     "search_memory (address, length, pattern) -> long\n\
874 Return a long with the address of a match, or None." },
875   /* thread_from_thread_handle is deprecated.  */
876   { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
877     METH_VARARGS | METH_KEYWORDS,
878     "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
879 Return thread object corresponding to thread handle.\n\
880 This method is deprecated - use thread_from_handle instead." },
881   { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
882     METH_VARARGS | METH_KEYWORDS,
883     "thread_from_handle (handle) -> gdb.InferiorThread.\n\
884 Return thread object corresponding to thread handle." },
885   { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
886     "architecture () -> gdb.Architecture\n\
887 Return architecture of this inferior." },
888   { NULL }
889 };
890 
891 PyTypeObject inferior_object_type =
892 {
893   PyVarObject_HEAD_INIT (NULL, 0)
894   "gdb.Inferior",		  /* tp_name */
895   sizeof (inferior_object),	  /* tp_basicsize */
896   0,				  /* tp_itemsize */
897   infpy_dealloc,		  /* tp_dealloc */
898   0,				  /* tp_print */
899   0,				  /* tp_getattr */
900   0,				  /* tp_setattr */
901   0,				  /* tp_compare */
902   infpy_repr,			  /* tp_repr */
903   0,				  /* tp_as_number */
904   0,				  /* tp_as_sequence */
905   0,				  /* tp_as_mapping */
906   0,				  /* tp_hash  */
907   0,				  /* tp_call */
908   0,				  /* tp_str */
909   0,				  /* tp_getattro */
910   0,				  /* tp_setattro */
911   0,				  /* tp_as_buffer */
912   Py_TPFLAGS_DEFAULT,		  /* tp_flags */
913   "GDB inferior object",	  /* tp_doc */
914   0,				  /* tp_traverse */
915   0,				  /* tp_clear */
916   0,				  /* tp_richcompare */
917   0,				  /* tp_weaklistoffset */
918   0,				  /* tp_iter */
919   0,				  /* tp_iternext */
920   inferior_object_methods,	  /* tp_methods */
921   0,				  /* tp_members */
922   inferior_object_getset,	  /* tp_getset */
923   0,				  /* tp_base */
924   0,				  /* tp_dict */
925   0,				  /* tp_descr_get */
926   0,				  /* tp_descr_set */
927   0,				  /* tp_dictoffset */
928   0,				  /* tp_init */
929   0				  /* tp_alloc */
930 };
931