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/>. */
21 #include "auto-load.h"
23 #include "gdbthread.h"
26 #include "observable.h"
27 #include "python-internal.h"
28 #include "arch-utils.h"
30 #include "gdbsupport/gdb_signals.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
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. */
60 extern PyTypeObject inferior_object_type
61 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
63 /* Deleter to clean up when an inferior is removed. */
66 void operator() (inferior_object
*obj
)
68 struct threadlist_entry
*th_entry
, *th_tmp
;
70 if (!gdb_python_initialized
)
74 gdbpy_ref
<inferior_object
> inf_obj (obj
);
76 inf_obj
->inferior
= NULL
;
78 /* Deallocate threads list. */
79 for (th_entry
= inf_obj
->threads
; th_entry
!= NULL
;)
82 th_entry
= th_entry
->next
;
86 inf_obj
->nthreads
= 0;
90 static const registry
<inferior
>::key
<inferior_object
, infpy_deleter
>
93 /* Require that INFERIOR be a valid inferior ID. */
94 #define INFPY_REQUIRE_VALID(Inferior) \
96 if (!Inferior->inferior) \
98 PyErr_SetString (PyExc_RuntimeError, \
99 _("Inferior no longer exists.")); \
105 python_on_normal_stop (struct bpstat
*bs
, int print_frame
)
107 enum gdb_signal stop_signal
;
109 if (!gdb_python_initialized
)
112 if (inferior_ptid
== null_ptid
)
115 stop_signal
= inferior_thread ()->stop_signal ();
117 gdbpy_enter enter_py
;
119 if (emit_stop_event (bs
, stop_signal
) < 0)
120 gdbpy_print_stack ();
124 python_on_resume (ptid_t ptid
)
126 if (!gdb_python_initialized
)
129 gdbpy_enter
enter_py (target_gdbarch ());
131 if (emit_continue_event (ptid
) < 0)
132 gdbpy_print_stack ();
135 /* Callback, registered as an observer, that notifies Python listeners
136 when an inferior function call is about to be made. */
139 python_on_inferior_call_pre (ptid_t thread
, CORE_ADDR address
)
141 gdbpy_enter
enter_py (target_gdbarch ());
143 if (emit_inferior_call_event (INFERIOR_CALL_PRE
, thread
, address
) < 0)
144 gdbpy_print_stack ();
147 /* Callback, registered as an observer, that notifies Python listeners
148 when an inferior function call has completed. */
151 python_on_inferior_call_post (ptid_t thread
, CORE_ADDR address
)
153 gdbpy_enter
enter_py (target_gdbarch ());
155 if (emit_inferior_call_event (INFERIOR_CALL_POST
, thread
, address
) < 0)
156 gdbpy_print_stack ();
159 /* Callback, registered as an observer, that notifies Python listeners
160 when a part of memory has been modified by user action (eg via a
164 python_on_memory_change (struct inferior
*inferior
, CORE_ADDR addr
, ssize_t len
, const bfd_byte
*data
)
166 gdbpy_enter
enter_py (target_gdbarch ());
168 if (emit_memory_changed_event (addr
, len
) < 0)
169 gdbpy_print_stack ();
172 /* Callback, registered as an observer, that notifies Python listeners
173 when a register has been modified by user action (eg via a 'set'
177 python_on_register_change (struct frame_info
*frame
, int regnum
)
179 gdbpy_enter
enter_py (target_gdbarch ());
181 if (emit_register_changed_event (frame
, regnum
) < 0)
182 gdbpy_print_stack ();
186 python_inferior_exit (struct inferior
*inf
)
188 const LONGEST
*exit_code
= NULL
;
190 if (!gdb_python_initialized
)
193 gdbpy_enter
enter_py (target_gdbarch ());
195 if (inf
->has_exit_code
)
196 exit_code
= &inf
->exit_code
;
198 if (emit_exited_event (exit_code
, inf
) < 0)
199 gdbpy_print_stack ();
202 /* Callback used to notify Python listeners about new objfiles loaded in the
203 inferior. OBJFILE may be NULL which means that the objfile list has been
204 cleared (emptied). */
207 python_new_objfile (struct objfile
*objfile
)
209 if (!gdb_python_initialized
)
212 gdbpy_enter
enter_py (objfile
!= NULL
214 : target_gdbarch ());
218 if (emit_clear_objfiles_event () < 0)
219 gdbpy_print_stack ();
223 if (emit_new_objfile_event (objfile
) < 0)
224 gdbpy_print_stack ();
228 /* Emit a Python event when an objfile is about to be removed. */
231 python_free_objfile (struct objfile
*objfile
)
233 if (!gdb_python_initialized
)
236 gdbpy_enter
enter_py (objfile
->arch ());
238 if (emit_free_objfile_event (objfile
) < 0)
239 gdbpy_print_stack ();
242 /* Return a reference to the Python object of type Inferior
243 representing INFERIOR. If the object has already been created,
244 return it and increment the reference count, otherwise, create it.
245 Return NULL on failure. */
247 gdbpy_ref
<inferior_object
>
248 inferior_to_inferior_object (struct inferior
*inferior
)
250 inferior_object
*inf_obj
;
252 inf_obj
= infpy_inf_data_key
.get (inferior
);
255 inf_obj
= PyObject_New (inferior_object
, &inferior_object_type
);
259 inf_obj
->inferior
= inferior
;
260 inf_obj
->threads
= NULL
;
261 inf_obj
->nthreads
= 0;
263 /* PyObject_New initializes the new object with a refcount of 1. This
264 counts for the reference we are keeping in the inferior data. */
265 infpy_inf_data_key
.set (inferior
, inf_obj
);
268 /* We are returning a new reference. */
269 gdb_assert (inf_obj
!= nullptr);
270 return gdbpy_ref
<inferior_object
>::new_reference (inf_obj
);
273 /* Called when a new inferior is created. Notifies any Python event
276 python_new_inferior (struct inferior
*inf
)
278 if (!gdb_python_initialized
)
281 gdbpy_enter enter_py
;
283 if (evregpy_no_listeners_p (gdb_py_events
.new_inferior
))
286 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
289 gdbpy_print_stack ();
293 gdbpy_ref
<> event
= create_event_object (&new_inferior_event_object_type
);
295 || evpy_add_attribute (event
.get (), "inferior",
296 (PyObject
*) inf_obj
.get ()) < 0
297 || evpy_emit_event (event
.get (), gdb_py_events
.new_inferior
) < 0)
298 gdbpy_print_stack ();
301 /* Called when an inferior is removed. Notifies any Python event
304 python_inferior_deleted (struct inferior
*inf
)
306 if (!gdb_python_initialized
)
309 gdbpy_enter enter_py
;
311 if (evregpy_no_listeners_p (gdb_py_events
.inferior_deleted
))
314 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
317 gdbpy_print_stack ();
321 gdbpy_ref
<> event
= create_event_object (&inferior_deleted_event_object_type
);
323 || evpy_add_attribute (event
.get (), "inferior",
324 (PyObject
*) inf_obj
.get ()) < 0
325 || evpy_emit_event (event
.get (), gdb_py_events
.inferior_deleted
) < 0)
326 gdbpy_print_stack ();
330 thread_to_thread_object (thread_info
*thr
)
332 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (thr
->inf
);
336 for (threadlist_entry
*thread
= inf_obj
->threads
;
338 thread
= thread
->next
)
339 if (thread
->thread_obj
->thread
== thr
)
340 return gdbpy_ref
<>::new_reference ((PyObject
*) thread
->thread_obj
.get ());
342 PyErr_SetString (PyExc_SystemError
,
343 _("could not find gdb thread object"));
348 add_thread_object (struct thread_info
*tp
)
350 inferior_object
*inf_obj
;
351 struct threadlist_entry
*entry
;
353 if (!gdb_python_initialized
)
356 gdbpy_enter enter_py
;
358 gdbpy_ref
<thread_object
> thread_obj
= create_thread_object (tp
);
359 if (thread_obj
== NULL
)
361 gdbpy_print_stack ();
365 inf_obj
= (inferior_object
*) thread_obj
->inf_obj
;
367 entry
= new threadlist_entry (std::move (thread_obj
));
368 entry
->next
= inf_obj
->threads
;
370 inf_obj
->threads
= entry
;
373 if (evregpy_no_listeners_p (gdb_py_events
.new_thread
))
376 gdbpy_ref
<> event
= create_thread_event_object (&new_thread_event_object_type
,
378 entry
->thread_obj
.get ());
380 || evpy_emit_event (event
.get (), gdb_py_events
.new_thread
) < 0)
381 gdbpy_print_stack ();
385 delete_thread_object (struct thread_info
*tp
, int ignore
)
387 struct threadlist_entry
**entry
, *tmp
;
389 if (!gdb_python_initialized
)
392 gdbpy_enter enter_py
;
394 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (tp
->inf
);
398 /* Find thread entry in its inferior's thread_list. */
399 for (entry
= &inf_obj
->threads
; *entry
!= NULL
; entry
=
401 if ((*entry
)->thread_obj
->thread
== tp
)
408 tmp
->thread_obj
->thread
= NULL
;
410 *entry
= (*entry
)->next
;
417 infpy_threads (PyObject
*self
, PyObject
*args
)
420 struct threadlist_entry
*entry
;
421 inferior_object
*inf_obj
= (inferior_object
*) self
;
424 INFPY_REQUIRE_VALID (inf_obj
);
428 update_thread_list ();
430 catch (const gdb_exception
&except
)
432 GDB_PY_HANDLE_EXCEPTION (except
);
435 tuple
= PyTuple_New (inf_obj
->nthreads
);
439 for (i
= 0, entry
= inf_obj
->threads
; i
< inf_obj
->nthreads
;
440 i
++, entry
= entry
->next
)
442 PyObject
*thr
= (PyObject
*) entry
->thread_obj
.get ();
444 PyTuple_SET_ITEM (tuple
, i
, thr
);
451 infpy_get_num (PyObject
*self
, void *closure
)
453 inferior_object
*inf
= (inferior_object
*) self
;
455 INFPY_REQUIRE_VALID (inf
);
457 return gdb_py_object_from_longest (inf
->inferior
->num
).release ();
460 /* Return the gdb.TargetConnection object for this inferior, or None if a
461 connection does not exist. */
464 infpy_get_connection (PyObject
*self
, void *closure
)
466 inferior_object
*inf
= (inferior_object
*) self
;
468 INFPY_REQUIRE_VALID (inf
);
470 process_stratum_target
*target
= inf
->inferior
->process_target ();
471 return target_to_connection_object (target
).release ();
474 /* Return the connection number of the given inferior, or None if a
475 connection does not exist. */
478 infpy_get_connection_num (PyObject
*self
, void *closure
)
480 inferior_object
*inf
= (inferior_object
*) self
;
482 INFPY_REQUIRE_VALID (inf
);
484 process_stratum_target
*target
= inf
->inferior
->process_target ();
485 if (target
== nullptr)
488 return gdb_py_object_from_longest (target
->connection_number
).release ();
492 infpy_get_pid (PyObject
*self
, void *closure
)
494 inferior_object
*inf
= (inferior_object
*) self
;
496 INFPY_REQUIRE_VALID (inf
);
498 return gdb_py_object_from_longest (inf
->inferior
->pid
).release ();
502 infpy_get_was_attached (PyObject
*self
, void *closure
)
504 inferior_object
*inf
= (inferior_object
*) self
;
506 INFPY_REQUIRE_VALID (inf
);
507 if (inf
->inferior
->attach_flag
)
512 /* Getter of gdb.Inferior.progspace. */
515 infpy_get_progspace (PyObject
*self
, void *closure
)
517 inferior_object
*inf
= (inferior_object
*) self
;
519 INFPY_REQUIRE_VALID (inf
);
521 program_space
*pspace
= inf
->inferior
->pspace
;
522 gdb_assert (pspace
!= nullptr);
524 return pspace_to_pspace_object (pspace
).release ();
527 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
528 Returns a tuple of all inferiors. */
530 gdbpy_inferiors (PyObject
*unused
, PyObject
*unused2
)
532 gdbpy_ref
<> list (PyList_New (0));
536 for (inferior
*inf
: all_inferiors ())
538 gdbpy_ref
<inferior_object
> inferior
= inferior_to_inferior_object (inf
);
540 if (inferior
== NULL
)
543 if (PyList_Append (list
.get (), (PyObject
*) inferior
.get ()) != 0)
547 return PyList_AsTuple (list
.get ());
550 /* Membuf and memory manipulation. */
552 /* Implementation of Inferior.read_memory (address, length).
553 Returns a Python buffer object with LENGTH bytes of the inferior's
554 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
555 with a python exception set. */
557 infpy_read_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
559 CORE_ADDR addr
, length
;
560 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer
;
561 PyObject
*addr_obj
, *length_obj
;
562 static const char *keywords
[] = { "address", "length", NULL
};
564 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OO", keywords
,
565 &addr_obj
, &length_obj
))
568 if (get_addr_from_python (addr_obj
, &addr
) < 0
569 || get_addr_from_python (length_obj
, &length
) < 0)
574 buffer
.reset ((gdb_byte
*) xmalloc (length
));
576 read_memory (addr
, buffer
.get (), length
);
578 catch (const gdb_exception
&except
)
580 GDB_PY_HANDLE_EXCEPTION (except
);
584 return gdbpy_buffer_to_membuf (std::move (buffer
), addr
, length
);
587 /* Implementation of Inferior.write_memory (address, buffer [, length]).
588 Writes the contents of BUFFER (a Python object supporting the read
589 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
590 bytes from BUFFER, or its entire contents if the argument is not
591 provided. The function returns nothing. Returns NULL on error, with
592 a python exception set. */
594 infpy_write_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
596 struct gdb_exception except
;
598 const gdb_byte
*buffer
;
599 CORE_ADDR addr
, length
;
600 PyObject
*addr_obj
, *length_obj
= NULL
;
601 static const char *keywords
[] = { "address", "buffer", "length", NULL
};
604 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "Os*|O", keywords
,
605 &addr_obj
, &pybuf
, &length_obj
))
608 Py_buffer_up
buffer_up (&pybuf
);
609 buffer
= (const gdb_byte
*) pybuf
.buf
;
612 if (get_addr_from_python (addr_obj
, &addr
) < 0)
617 else if (get_addr_from_python (length_obj
, &length
) < 0)
622 write_memory_with_notification (addr
, buffer
, length
);
624 catch (gdb_exception
&ex
)
626 except
= std::move (ex
);
629 GDB_PY_HANDLE_EXCEPTION (except
);
635 gdb.search_memory (address, length, pattern). ADDRESS is the
636 address to start the search. LENGTH specifies the scope of the
637 search from ADDRESS. PATTERN is the pattern to search for (and
638 must be a Python object supporting the buffer protocol).
639 Returns a Python Long object holding the address where the pattern
640 was located, or if the pattern was not found, returns None. Returns NULL
641 on error, with a python exception set. */
643 infpy_search_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
645 struct gdb_exception except
;
646 CORE_ADDR start_addr
, length
;
647 static const char *keywords
[] = { "address", "length", "pattern", NULL
};
648 PyObject
*start_addr_obj
, *length_obj
;
649 Py_ssize_t pattern_size
;
650 const gdb_byte
*buffer
;
651 CORE_ADDR found_addr
;
655 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OOs*", keywords
,
656 &start_addr_obj
, &length_obj
,
660 Py_buffer_up
buffer_up (&pybuf
);
661 buffer
= (const gdb_byte
*) pybuf
.buf
;
662 pattern_size
= pybuf
.len
;
664 if (get_addr_from_python (start_addr_obj
, &start_addr
) < 0)
667 if (get_addr_from_python (length_obj
, &length
) < 0)
672 PyErr_SetString (PyExc_ValueError
,
673 _("Search range is empty."));
676 /* Watch for overflows. */
677 else if (length
> CORE_ADDR_MAX
678 || (start_addr
+ length
- 1) < start_addr
)
680 PyErr_SetString (PyExc_ValueError
,
681 _("The search range is too large."));
687 found
= target_search_memory (start_addr
, length
,
688 buffer
, pattern_size
,
691 catch (gdb_exception
&ex
)
693 except
= std::move (ex
);
696 GDB_PY_HANDLE_EXCEPTION (except
);
699 return gdb_py_object_from_ulongest (found_addr
).release ();
704 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
705 Returns True if this inferior object still exists in GDB. */
708 infpy_is_valid (PyObject
*self
, PyObject
*args
)
710 inferior_object
*inf
= (inferior_object
*) self
;
718 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
719 -> gdb.InferiorThread. */
722 infpy_thread_from_thread_handle (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
724 PyObject
*handle_obj
;
725 inferior_object
*inf_obj
= (inferior_object
*) self
;
726 static const char *keywords
[] = { "handle", NULL
};
728 INFPY_REQUIRE_VALID (inf_obj
);
730 if (! gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "O", keywords
, &handle_obj
))
733 const gdb_byte
*bytes
;
735 Py_buffer_up buffer_up
;
738 if (PyObject_CheckBuffer (handle_obj
)
739 && PyObject_GetBuffer (handle_obj
, &py_buf
, PyBUF_SIMPLE
) == 0)
741 buffer_up
.reset (&py_buf
);
742 bytes
= (const gdb_byte
*) py_buf
.buf
;
743 bytes_len
= py_buf
.len
;
745 else if (gdbpy_is_value_object (handle_obj
))
747 struct value
*val
= value_object_to_value (handle_obj
);
748 bytes
= value_contents_all (val
).data ();
749 bytes_len
= value_type (val
)->length ();
753 PyErr_SetString (PyExc_TypeError
,
754 _("Argument 'handle' must be a thread handle object."));
761 struct thread_info
*thread_info
;
763 thread_info
= find_thread_by_handle
764 (gdb::array_view
<const gdb_byte
> (bytes
, bytes_len
),
766 if (thread_info
!= NULL
)
767 return thread_to_thread_object (thread_info
).release ();
769 catch (const gdb_exception
&except
)
771 GDB_PY_HANDLE_EXCEPTION (except
);
777 /* Implementation of gdb.Inferior.architecture. */
780 infpy_architecture (PyObject
*self
, PyObject
*args
)
782 inferior_object
*inf
= (inferior_object
*) self
;
784 INFPY_REQUIRE_VALID (inf
);
786 return gdbarch_to_arch_object (inf
->inferior
->gdbarch
);
789 /* Implement repr() for gdb.Inferior. */
792 infpy_repr (PyObject
*obj
)
794 inferior_object
*self
= (inferior_object
*) obj
;
795 inferior
*inf
= self
->inferior
;
798 return PyUnicode_FromString ("<gdb.Inferior (invalid)>");
800 return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
806 infpy_dealloc (PyObject
*obj
)
808 inferior_object
*inf_obj
= (inferior_object
*) obj
;
810 /* The inferior itself holds a reference to this Python object, which
811 will keep the reference count of this object above zero until GDB
812 deletes the inferior and py_free_inferior is called.
814 Once py_free_inferior has been called then the link between this
815 Python object and the inferior is set to nullptr, and then the
816 reference count on this Python object is decremented.
818 The result of all this is that the link between this Python object and
819 the inferior should always have been set to nullptr before this
820 function is called. */
821 gdb_assert (inf_obj
->inferior
== nullptr);
823 Py_TYPE (obj
)->tp_free (obj
);
826 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
827 Returns the current inferior object. */
830 gdbpy_selected_inferior (PyObject
*self
, PyObject
*args
)
833 inferior_to_inferior_object (current_inferior ()).release ());
837 gdbpy_initialize_inferior (void)
839 if (PyType_Ready (&inferior_object_type
) < 0)
842 if (gdb_pymodule_addobject (gdb_module
, "Inferior",
843 (PyObject
*) &inferior_object_type
) < 0)
846 gdb::observers::new_thread
.attach (add_thread_object
, "py-inferior");
847 gdb::observers::thread_exit
.attach (delete_thread_object
, "py-inferior");
848 gdb::observers::normal_stop
.attach (python_on_normal_stop
, "py-inferior");
849 gdb::observers::target_resumed
.attach (python_on_resume
, "py-inferior");
850 gdb::observers::inferior_call_pre
.attach (python_on_inferior_call_pre
,
852 gdb::observers::inferior_call_post
.attach (python_on_inferior_call_post
,
854 gdb::observers::memory_changed
.attach (python_on_memory_change
,
856 gdb::observers::register_changed
.attach (python_on_register_change
,
858 gdb::observers::inferior_exit
.attach (python_inferior_exit
, "py-inferior");
859 /* Need to run after auto-load's new_objfile observer, so that
860 auto-loaded pretty-printers are available. */
861 gdb::observers::new_objfile
.attach
862 (python_new_objfile
, "py-inferior",
863 { &auto_load_new_objfile_observer_token
});
864 gdb::observers::free_objfile
.attach (python_free_objfile
, "py-inferior");
865 gdb::observers::inferior_added
.attach (python_new_inferior
, "py-inferior");
866 gdb::observers::inferior_removed
.attach (python_inferior_deleted
,
872 static gdb_PyGetSetDef inferior_object_getset
[] =
874 { "num", infpy_get_num
, NULL
, "ID of inferior, as assigned by GDB.", NULL
},
875 { "connection", infpy_get_connection
, NULL
,
876 "The gdb.TargetConnection for this inferior.", NULL
},
877 { "connection_num", infpy_get_connection_num
, NULL
,
878 "ID of inferior's connection, as assigned by GDB.", NULL
},
879 { "pid", infpy_get_pid
, NULL
, "PID of inferior, as assigned by the OS.",
881 { "was_attached", infpy_get_was_attached
, NULL
,
882 "True if the inferior was created using 'attach'.", NULL
},
883 { "progspace", infpy_get_progspace
, NULL
, "Program space of this inferior" },
887 static PyMethodDef inferior_object_methods
[] =
889 { "is_valid", infpy_is_valid
, METH_NOARGS
,
890 "is_valid () -> Boolean.\n\
891 Return true if this inferior is valid, false if not." },
892 { "threads", infpy_threads
, METH_NOARGS
,
893 "Return all the threads of this inferior." },
894 { "read_memory", (PyCFunction
) infpy_read_memory
,
895 METH_VARARGS
| METH_KEYWORDS
,
896 "read_memory (address, length) -> buffer\n\
897 Return a buffer object for reading from the inferior's memory." },
898 { "write_memory", (PyCFunction
) infpy_write_memory
,
899 METH_VARARGS
| METH_KEYWORDS
,
900 "write_memory (address, buffer [, length])\n\
901 Write the given buffer object to the inferior's memory." },
902 { "search_memory", (PyCFunction
) infpy_search_memory
,
903 METH_VARARGS
| METH_KEYWORDS
,
904 "search_memory (address, length, pattern) -> long\n\
905 Return a long with the address of a match, or None." },
906 /* thread_from_thread_handle is deprecated. */
907 { "thread_from_thread_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
908 METH_VARARGS
| METH_KEYWORDS
,
909 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
910 Return thread object corresponding to thread handle.\n\
911 This method is deprecated - use thread_from_handle instead." },
912 { "thread_from_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
913 METH_VARARGS
| METH_KEYWORDS
,
914 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
915 Return thread object corresponding to thread handle." },
916 { "architecture", (PyCFunction
) infpy_architecture
, METH_NOARGS
,
917 "architecture () -> gdb.Architecture\n\
918 Return architecture of this inferior." },
922 PyTypeObject inferior_object_type
=
924 PyVarObject_HEAD_INIT (NULL
, 0)
925 "gdb.Inferior", /* tp_name */
926 sizeof (inferior_object
), /* tp_basicsize */
928 infpy_dealloc
, /* tp_dealloc */
933 infpy_repr
, /* tp_repr */
934 0, /* tp_as_number */
935 0, /* tp_as_sequence */
936 0, /* tp_as_mapping */
942 0, /* tp_as_buffer */
943 Py_TPFLAGS_DEFAULT
, /* tp_flags */
944 "GDB inferior object", /* tp_doc */
947 0, /* tp_richcompare */
948 0, /* tp_weaklistoffset */
951 inferior_object_methods
, /* tp_methods */
953 inferior_object_getset
, /* tp_getset */
956 0, /* tp_descr_get */
957 0, /* tp_descr_set */
958 0, /* tp_dictoffset */