Automatic Copyright Year update after running gdb/copyright.py
[binutils-gdb.git] / gdb / python / py-inferior.c
blob6b1443db2a842e1b93494dd67da048b230064406
1 /* Python interface to inferiors.
3 Copyright (C) 2009-2022 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
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"
34 struct threadlist_entry
36 threadlist_entry (gdbpy_ref<thread_object> &&ref)
37 : thread_obj (std::move (ref))
41 gdbpy_ref<thread_object> thread_obj;
42 struct threadlist_entry *next;
45 struct inferior_object
47 PyObject_HEAD
49 /* The inferior we represent. */
50 struct inferior *inferior;
52 /* thread_object instances under this inferior. This list owns a
53 reference to each object it contains. */
54 struct threadlist_entry *threads;
56 /* Number of threads in the list. */
57 int nthreads;
60 extern PyTypeObject inferior_object_type
61 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
63 static const struct inferior_data *infpy_inf_data_key;
65 /* Require that INFERIOR be a valid inferior ID. */
66 #define INFPY_REQUIRE_VALID(Inferior) \
67 do { \
68 if (!Inferior->inferior) \
69 { \
70 PyErr_SetString (PyExc_RuntimeError, \
71 _("Inferior no longer exists.")); \
72 return NULL; \
73 } \
74 } while (0)
76 static void
77 python_on_normal_stop (struct bpstat *bs, int print_frame)
79 enum gdb_signal stop_signal;
81 if (!gdb_python_initialized)
82 return;
84 if (inferior_ptid == null_ptid)
85 return;
87 stop_signal = inferior_thread ()->stop_signal ();
89 gdbpy_enter enter_py (get_current_arch (), current_language);
91 if (emit_stop_event (bs, stop_signal) < 0)
92 gdbpy_print_stack ();
95 static void
96 python_on_resume (ptid_t ptid)
98 if (!gdb_python_initialized)
99 return;
101 gdbpy_enter enter_py (target_gdbarch (), current_language);
103 if (emit_continue_event (ptid) < 0)
104 gdbpy_print_stack ();
107 /* Callback, registered as an observer, that notifies Python listeners
108 when an inferior function call is about to be made. */
110 static void
111 python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
113 gdbpy_enter enter_py (target_gdbarch (), current_language);
115 if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
116 gdbpy_print_stack ();
119 /* Callback, registered as an observer, that notifies Python listeners
120 when an inferior function call has completed. */
122 static void
123 python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
125 gdbpy_enter enter_py (target_gdbarch (), current_language);
127 if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
128 gdbpy_print_stack ();
131 /* Callback, registered as an observer, that notifies Python listeners
132 when a part of memory has been modified by user action (eg via a
133 'set' command). */
135 static void
136 python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
138 gdbpy_enter enter_py (target_gdbarch (), current_language);
140 if (emit_memory_changed_event (addr, len) < 0)
141 gdbpy_print_stack ();
144 /* Callback, registered as an observer, that notifies Python listeners
145 when a register has been modified by user action (eg via a 'set'
146 command). */
148 static void
149 python_on_register_change (struct frame_info *frame, int regnum)
151 gdbpy_enter enter_py (target_gdbarch (), current_language);
153 if (emit_register_changed_event (frame, regnum) < 0)
154 gdbpy_print_stack ();
157 static void
158 python_inferior_exit (struct inferior *inf)
160 const LONGEST *exit_code = NULL;
162 if (!gdb_python_initialized)
163 return;
165 gdbpy_enter enter_py (target_gdbarch (), current_language);
167 if (inf->has_exit_code)
168 exit_code = &inf->exit_code;
170 if (emit_exited_event (exit_code, inf) < 0)
171 gdbpy_print_stack ();
174 /* Callback used to notify Python listeners about new objfiles loaded in the
175 inferior. OBJFILE may be NULL which means that the objfile list has been
176 cleared (emptied). */
178 static void
179 python_new_objfile (struct objfile *objfile)
181 if (!gdb_python_initialized)
182 return;
184 gdbpy_enter enter_py (objfile != NULL
185 ? objfile->arch ()
186 : target_gdbarch (),
187 current_language);
189 if (objfile == NULL)
191 if (emit_clear_objfiles_event () < 0)
192 gdbpy_print_stack ();
194 else
196 if (emit_new_objfile_event (objfile) < 0)
197 gdbpy_print_stack ();
201 /* Return a reference to the Python object of type Inferior
202 representing INFERIOR. If the object has already been created,
203 return it and increment the reference count, otherwise, create it.
204 Return NULL on failure. */
206 gdbpy_ref<inferior_object>
207 inferior_to_inferior_object (struct inferior *inferior)
209 inferior_object *inf_obj;
211 inf_obj = (inferior_object *) inferior_data (inferior, infpy_inf_data_key);
212 if (!inf_obj)
214 inf_obj = PyObject_New (inferior_object, &inferior_object_type);
215 if (!inf_obj)
216 return NULL;
218 inf_obj->inferior = inferior;
219 inf_obj->threads = NULL;
220 inf_obj->nthreads = 0;
222 /* PyObject_New initializes the new object with a refcount of 1. This
223 counts for the reference we are keeping in the inferior data. */
224 set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
227 /* We are returning a new reference. */
228 gdb_assert (inf_obj != nullptr);
229 return gdbpy_ref<inferior_object>::new_reference (inf_obj);
232 /* Called when a new inferior is created. Notifies any Python event
233 listeners. */
234 static void
235 python_new_inferior (struct inferior *inf)
237 if (!gdb_python_initialized)
238 return;
240 gdbpy_enter enter_py (python_gdbarch, python_language);
242 if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
243 return;
245 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
246 if (inf_obj == NULL)
248 gdbpy_print_stack ();
249 return;
252 gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
253 if (event == NULL
254 || evpy_add_attribute (event.get (), "inferior",
255 (PyObject *) inf_obj.get ()) < 0
256 || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
257 gdbpy_print_stack ();
260 /* Called when an inferior is removed. Notifies any Python event
261 listeners. */
262 static void
263 python_inferior_deleted (struct inferior *inf)
265 if (!gdb_python_initialized)
266 return;
268 gdbpy_enter enter_py (python_gdbarch, python_language);
270 if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
271 return;
273 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
274 if (inf_obj == NULL)
276 gdbpy_print_stack ();
277 return;
280 gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
281 if (event == NULL
282 || evpy_add_attribute (event.get (), "inferior",
283 (PyObject *) inf_obj.get ()) < 0
284 || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
285 gdbpy_print_stack ();
288 gdbpy_ref<>
289 thread_to_thread_object (thread_info *thr)
291 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
292 if (inf_obj == NULL)
293 return NULL;
295 for (threadlist_entry *thread = inf_obj->threads;
296 thread != NULL;
297 thread = thread->next)
298 if (thread->thread_obj->thread == thr)
299 return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj.get ());
301 PyErr_SetString (PyExc_SystemError,
302 _("could not find gdb thread object"));
303 return NULL;
306 static void
307 add_thread_object (struct thread_info *tp)
309 inferior_object *inf_obj;
310 struct threadlist_entry *entry;
312 if (!gdb_python_initialized)
313 return;
315 gdbpy_enter enter_py (python_gdbarch, python_language);
317 gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
318 if (thread_obj == NULL)
320 gdbpy_print_stack ();
321 return;
324 inf_obj = (inferior_object *) thread_obj->inf_obj;
326 entry = new threadlist_entry (std::move (thread_obj));
327 entry->next = inf_obj->threads;
329 inf_obj->threads = entry;
330 inf_obj->nthreads++;
332 if (evregpy_no_listeners_p (gdb_py_events.new_thread))
333 return;
335 gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type,
336 (PyObject *) inf_obj);
337 if (event == NULL
338 || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
339 gdbpy_print_stack ();
342 static void
343 delete_thread_object (struct thread_info *tp, int ignore)
345 struct threadlist_entry **entry, *tmp;
347 if (!gdb_python_initialized)
348 return;
350 gdbpy_enter enter_py (python_gdbarch, python_language);
352 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
353 if (inf_obj == NULL)
354 return;
356 /* Find thread entry in its inferior's thread_list. */
357 for (entry = &inf_obj->threads; *entry != NULL; entry =
358 &(*entry)->next)
359 if ((*entry)->thread_obj->thread == tp)
360 break;
362 if (!*entry)
363 return;
365 tmp = *entry;
366 tmp->thread_obj->thread = NULL;
368 *entry = (*entry)->next;
369 inf_obj->nthreads--;
371 delete tmp;
374 static PyObject *
375 infpy_threads (PyObject *self, PyObject *args)
377 int i;
378 struct threadlist_entry *entry;
379 inferior_object *inf_obj = (inferior_object *) self;
380 PyObject *tuple;
382 INFPY_REQUIRE_VALID (inf_obj);
386 update_thread_list ();
388 catch (const gdb_exception &except)
390 GDB_PY_HANDLE_EXCEPTION (except);
393 tuple = PyTuple_New (inf_obj->nthreads);
394 if (!tuple)
395 return NULL;
397 for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
398 i++, entry = entry->next)
400 PyObject *thr = (PyObject *) entry->thread_obj.get ();
401 Py_INCREF (thr);
402 PyTuple_SET_ITEM (tuple, i, thr);
405 return tuple;
408 static PyObject *
409 infpy_get_num (PyObject *self, void *closure)
411 inferior_object *inf = (inferior_object *) self;
413 INFPY_REQUIRE_VALID (inf);
415 return gdb_py_object_from_longest (inf->inferior->num).release ();
418 /* Return the gdb.TargetConnection object for this inferior, or None if a
419 connection does not exist. */
421 static PyObject *
422 infpy_get_connection (PyObject *self, void *closure)
424 inferior_object *inf = (inferior_object *) self;
426 INFPY_REQUIRE_VALID (inf);
428 process_stratum_target *target = inf->inferior->process_target ();
429 return target_to_connection_object (target).release ();
432 /* Return the connection number of the given inferior, or None if a
433 connection does not exist. */
435 static PyObject *
436 infpy_get_connection_num (PyObject *self, void *closure)
438 inferior_object *inf = (inferior_object *) self;
440 INFPY_REQUIRE_VALID (inf);
442 process_stratum_target *target = inf->inferior->process_target ();
443 if (target == nullptr)
444 Py_RETURN_NONE;
446 return gdb_py_object_from_longest (target->connection_number).release ();
449 static PyObject *
450 infpy_get_pid (PyObject *self, void *closure)
452 inferior_object *inf = (inferior_object *) self;
454 INFPY_REQUIRE_VALID (inf);
456 return gdb_py_object_from_longest (inf->inferior->pid).release ();
459 static PyObject *
460 infpy_get_was_attached (PyObject *self, void *closure)
462 inferior_object *inf = (inferior_object *) self;
464 INFPY_REQUIRE_VALID (inf);
465 if (inf->inferior->attach_flag)
466 Py_RETURN_TRUE;
467 Py_RETURN_FALSE;
470 /* Getter of gdb.Inferior.progspace. */
472 static PyObject *
473 infpy_get_progspace (PyObject *self, void *closure)
475 inferior_object *inf = (inferior_object *) self;
477 INFPY_REQUIRE_VALID (inf);
479 program_space *pspace = inf->inferior->pspace;
480 gdb_assert (pspace != nullptr);
482 return pspace_to_pspace_object (pspace).release ();
485 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
486 Returns a tuple of all inferiors. */
487 PyObject *
488 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
490 gdbpy_ref<> list (PyList_New (0));
491 if (list == NULL)
492 return NULL;
494 for (inferior *inf : all_inferiors ())
496 gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
498 if (inferior == NULL)
499 continue;
501 if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
502 return NULL;
505 return PyList_AsTuple (list.get ());
508 /* Membuf and memory manipulation. */
510 /* Implementation of Inferior.read_memory (address, length).
511 Returns a Python buffer object with LENGTH bytes of the inferior's
512 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
513 with a python exception set. */
514 static PyObject *
515 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
517 CORE_ADDR addr, length;
518 gdb::unique_xmalloc_ptr<gdb_byte> buffer;
519 PyObject *addr_obj, *length_obj;
520 static const char *keywords[] = { "address", "length", NULL };
522 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
523 &addr_obj, &length_obj))
524 return NULL;
526 if (get_addr_from_python (addr_obj, &addr) < 0
527 || get_addr_from_python (length_obj, &length) < 0)
528 return NULL;
532 buffer.reset ((gdb_byte *) xmalloc (length));
534 read_memory (addr, buffer.get (), length);
536 catch (const gdb_exception &except)
538 GDB_PY_HANDLE_EXCEPTION (except);
542 return gdbpy_buffer_to_membuf (std::move (buffer), addr, length);
545 /* Implementation of Inferior.write_memory (address, buffer [, length]).
546 Writes the contents of BUFFER (a Python object supporting the read
547 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
548 bytes from BUFFER, or its entire contents if the argument is not
549 provided. The function returns nothing. Returns NULL on error, with
550 a python exception set. */
551 static PyObject *
552 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
554 struct gdb_exception except;
555 Py_ssize_t buf_len;
556 const gdb_byte *buffer;
557 CORE_ADDR addr, length;
558 PyObject *addr_obj, *length_obj = NULL;
559 static const char *keywords[] = { "address", "buffer", "length", NULL };
560 Py_buffer pybuf;
562 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
563 &addr_obj, &pybuf, &length_obj))
564 return NULL;
566 Py_buffer_up buffer_up (&pybuf);
567 buffer = (const gdb_byte *) pybuf.buf;
568 buf_len = pybuf.len;
570 if (get_addr_from_python (addr_obj, &addr) < 0)
571 return nullptr;
573 if (!length_obj)
574 length = buf_len;
575 else if (get_addr_from_python (length_obj, &length) < 0)
576 return nullptr;
580 write_memory_with_notification (addr, buffer, length);
582 catch (gdb_exception &ex)
584 except = std::move (ex);
587 GDB_PY_HANDLE_EXCEPTION (except);
589 Py_RETURN_NONE;
592 /* Implementation of
593 gdb.search_memory (address, length, pattern). ADDRESS is the
594 address to start the search. LENGTH specifies the scope of the
595 search from ADDRESS. PATTERN is the pattern to search for (and
596 must be a Python object supporting the buffer protocol).
597 Returns a Python Long object holding the address where the pattern
598 was located, or if the pattern was not found, returns None. Returns NULL
599 on error, with a python exception set. */
600 static PyObject *
601 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
603 struct gdb_exception except;
604 CORE_ADDR start_addr, length;
605 static const char *keywords[] = { "address", "length", "pattern", NULL };
606 PyObject *start_addr_obj, *length_obj;
607 Py_ssize_t pattern_size;
608 const gdb_byte *buffer;
609 CORE_ADDR found_addr;
610 int found = 0;
611 Py_buffer pybuf;
613 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
614 &start_addr_obj, &length_obj,
615 &pybuf))
616 return NULL;
618 Py_buffer_up buffer_up (&pybuf);
619 buffer = (const gdb_byte *) pybuf.buf;
620 pattern_size = pybuf.len;
622 if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
623 return nullptr;
625 if (get_addr_from_python (length_obj, &length) < 0)
626 return nullptr;
628 if (!length)
630 PyErr_SetString (PyExc_ValueError,
631 _("Search range is empty."));
632 return nullptr;
634 /* Watch for overflows. */
635 else if (length > CORE_ADDR_MAX
636 || (start_addr + length - 1) < start_addr)
638 PyErr_SetString (PyExc_ValueError,
639 _("The search range is too large."));
640 return nullptr;
645 found = target_search_memory (start_addr, length,
646 buffer, pattern_size,
647 &found_addr);
649 catch (gdb_exception &ex)
651 except = std::move (ex);
654 GDB_PY_HANDLE_EXCEPTION (except);
656 if (found)
657 return gdb_py_object_from_ulongest (found_addr).release ();
658 else
659 Py_RETURN_NONE;
662 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
663 Returns True if this inferior object still exists in GDB. */
665 static PyObject *
666 infpy_is_valid (PyObject *self, PyObject *args)
668 inferior_object *inf = (inferior_object *) self;
670 if (! inf->inferior)
671 Py_RETURN_FALSE;
673 Py_RETURN_TRUE;
676 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
677 -> gdb.InferiorThread. */
679 static PyObject *
680 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
682 PyObject *handle_obj;
683 inferior_object *inf_obj = (inferior_object *) self;
684 static const char *keywords[] = { "handle", NULL };
686 INFPY_REQUIRE_VALID (inf_obj);
688 if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
689 return NULL;
691 const gdb_byte *bytes;
692 size_t bytes_len;
693 Py_buffer_up buffer_up;
694 Py_buffer py_buf;
696 if (PyObject_CheckBuffer (handle_obj)
697 && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
699 buffer_up.reset (&py_buf);
700 bytes = (const gdb_byte *) py_buf.buf;
701 bytes_len = py_buf.len;
703 else if (gdbpy_is_value_object (handle_obj))
705 struct value *val = value_object_to_value (handle_obj);
706 bytes = value_contents_all (val).data ();
707 bytes_len = TYPE_LENGTH (value_type (val));
709 else
711 PyErr_SetString (PyExc_TypeError,
712 _("Argument 'handle' must be a thread handle object."));
714 return NULL;
719 struct thread_info *thread_info;
721 thread_info = find_thread_by_handle
722 (gdb::array_view<const gdb_byte> (bytes, bytes_len),
723 inf_obj->inferior);
724 if (thread_info != NULL)
725 return thread_to_thread_object (thread_info).release ();
727 catch (const gdb_exception &except)
729 GDB_PY_HANDLE_EXCEPTION (except);
732 Py_RETURN_NONE;
735 /* Implementation of gdb.Inferior.architecture. */
737 static PyObject *
738 infpy_architecture (PyObject *self, PyObject *args)
740 inferior_object *inf = (inferior_object *) self;
742 INFPY_REQUIRE_VALID (inf);
744 return gdbarch_to_arch_object (inf->inferior->gdbarch);
747 /* Implement repr() for gdb.Inferior. */
749 static PyObject *
750 infpy_repr (PyObject *obj)
752 inferior_object *self = (inferior_object *) obj;
753 inferior *inf = self->inferior;
755 if (inf == nullptr)
756 return PyString_FromString ("<gdb.Inferior (invalid)>");
758 return PyString_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
759 inf->num, inf->pid);
763 static void
764 infpy_dealloc (PyObject *obj)
766 inferior_object *inf_obj = (inferior_object *) obj;
768 /* The inferior itself holds a reference to this Python object, which
769 will keep the reference count of this object above zero until GDB
770 deletes the inferior and py_free_inferior is called.
772 Once py_free_inferior has been called then the link between this
773 Python object and the inferior is set to nullptr, and then the
774 reference count on this Python object is decremented.
776 The result of all this is that the link between this Python object and
777 the inferior should always have been set to nullptr before this
778 function is called. */
779 gdb_assert (inf_obj->inferior == nullptr);
781 Py_TYPE (obj)->tp_free (obj);
784 /* Clear the INFERIOR pointer in an Inferior object and clear the
785 thread list. */
786 static void
787 py_free_inferior (struct inferior *inf, void *datum)
789 struct threadlist_entry *th_entry, *th_tmp;
791 if (!gdb_python_initialized)
792 return;
794 gdbpy_enter enter_py (python_gdbarch, python_language);
795 gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
797 inf_obj->inferior = NULL;
799 /* Deallocate threads list. */
800 for (th_entry = inf_obj->threads; th_entry != NULL;)
802 th_tmp = th_entry;
803 th_entry = th_entry->next;
804 delete th_tmp;
807 inf_obj->nthreads = 0;
810 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
811 Returns the current inferior object. */
813 PyObject *
814 gdbpy_selected_inferior (PyObject *self, PyObject *args)
816 return ((PyObject *)
817 inferior_to_inferior_object (current_inferior ()).release ());
820 void _initialize_py_inferior ();
821 void
822 _initialize_py_inferior ()
824 infpy_inf_data_key =
825 register_inferior_data_with_cleanup (NULL, py_free_inferior);
829 gdbpy_initialize_inferior (void)
831 if (PyType_Ready (&inferior_object_type) < 0)
832 return -1;
834 if (gdb_pymodule_addobject (gdb_module, "Inferior",
835 (PyObject *) &inferior_object_type) < 0)
836 return -1;
838 gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
839 gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
840 gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
841 gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
842 gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
843 "py-inferior");
844 gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
845 "py-inferior");
846 gdb::observers::memory_changed.attach (python_on_memory_change,
847 "py-inferior");
848 gdb::observers::register_changed.attach (python_on_register_change,
849 "py-inferior");
850 gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
851 /* Need to run after auto-load's new_objfile observer, so that
852 auto-loaded pretty-printers are available. */
853 gdb::observers::new_objfile.attach
854 (python_new_objfile, "py-inferior",
855 { &auto_load_new_objfile_observer_token });
856 gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
857 gdb::observers::inferior_removed.attach (python_inferior_deleted,
858 "py-inferior");
860 return 0;
863 static gdb_PyGetSetDef inferior_object_getset[] =
865 { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
866 { "connection", infpy_get_connection, NULL,
867 "The gdb.TargetConnection for this inferior.", NULL },
868 { "connection_num", infpy_get_connection_num, NULL,
869 "ID of inferior's connection, as assigned by GDB.", NULL },
870 { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
871 NULL },
872 { "was_attached", infpy_get_was_attached, NULL,
873 "True if the inferior was created using 'attach'.", NULL },
874 { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
875 { NULL }
878 static PyMethodDef inferior_object_methods[] =
880 { "is_valid", infpy_is_valid, METH_NOARGS,
881 "is_valid () -> Boolean.\n\
882 Return true if this inferior is valid, false if not." },
883 { "threads", infpy_threads, METH_NOARGS,
884 "Return all the threads of this inferior." },
885 { "read_memory", (PyCFunction) infpy_read_memory,
886 METH_VARARGS | METH_KEYWORDS,
887 "read_memory (address, length) -> buffer\n\
888 Return a buffer object for reading from the inferior's memory." },
889 { "write_memory", (PyCFunction) infpy_write_memory,
890 METH_VARARGS | METH_KEYWORDS,
891 "write_memory (address, buffer [, length])\n\
892 Write the given buffer object to the inferior's memory." },
893 { "search_memory", (PyCFunction) infpy_search_memory,
894 METH_VARARGS | METH_KEYWORDS,
895 "search_memory (address, length, pattern) -> long\n\
896 Return a long with the address of a match, or None." },
897 /* thread_from_thread_handle is deprecated. */
898 { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
899 METH_VARARGS | METH_KEYWORDS,
900 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
901 Return thread object corresponding to thread handle.\n\
902 This method is deprecated - use thread_from_handle instead." },
903 { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
904 METH_VARARGS | METH_KEYWORDS,
905 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
906 Return thread object corresponding to thread handle." },
907 { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
908 "architecture () -> gdb.Architecture\n\
909 Return architecture of this inferior." },
910 { NULL }
913 PyTypeObject inferior_object_type =
915 PyVarObject_HEAD_INIT (NULL, 0)
916 "gdb.Inferior", /* tp_name */
917 sizeof (inferior_object), /* tp_basicsize */
918 0, /* tp_itemsize */
919 infpy_dealloc, /* tp_dealloc */
920 0, /* tp_print */
921 0, /* tp_getattr */
922 0, /* tp_setattr */
923 0, /* tp_compare */
924 infpy_repr, /* tp_repr */
925 0, /* tp_as_number */
926 0, /* tp_as_sequence */
927 0, /* tp_as_mapping */
928 0, /* tp_hash */
929 0, /* tp_call */
930 0, /* tp_str */
931 0, /* tp_getattro */
932 0, /* tp_setattro */
933 0, /* tp_as_buffer */
934 Py_TPFLAGS_DEFAULT, /* tp_flags */
935 "GDB inferior object", /* tp_doc */
936 0, /* tp_traverse */
937 0, /* tp_clear */
938 0, /* tp_richcompare */
939 0, /* tp_weaklistoffset */
940 0, /* tp_iter */
941 0, /* tp_iternext */
942 inferior_object_methods, /* tp_methods */
943 0, /* tp_members */
944 inferior_object_getset, /* tp_getset */
945 0, /* tp_base */
946 0, /* tp_dict */
947 0, /* tp_descr_get */
948 0, /* tp_descr_set */
949 0, /* tp_dictoffset */
950 0, /* tp_init */
951 0 /* tp_alloc */