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 static const struct inferior_data
*infpy_inf_data_key
;
65 /* Require that INFERIOR be a valid inferior ID. */
66 #define INFPY_REQUIRE_VALID(Inferior) \
68 if (!Inferior->inferior) \
70 PyErr_SetString (PyExc_RuntimeError, \
71 _("Inferior no longer exists.")); \
77 python_on_normal_stop (struct bpstat
*bs
, int print_frame
)
79 enum gdb_signal stop_signal
;
81 if (!gdb_python_initialized
)
84 if (inferior_ptid
== null_ptid
)
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)
96 python_on_resume (ptid_t ptid
)
98 if (!gdb_python_initialized
)
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. */
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. */
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
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'
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 ();
158 python_inferior_exit (struct inferior
*inf
)
160 const LONGEST
*exit_code
= NULL
;
162 if (!gdb_python_initialized
)
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). */
179 python_new_objfile (struct objfile
*objfile
)
181 if (!gdb_python_initialized
)
184 gdbpy_enter
enter_py (objfile
!= NULL
191 if (emit_clear_objfiles_event () < 0)
192 gdbpy_print_stack ();
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
);
214 inf_obj
= PyObject_New (inferior_object
, &inferior_object_type
);
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
235 python_new_inferior (struct inferior
*inf
)
237 if (!gdb_python_initialized
)
240 gdbpy_enter
enter_py (python_gdbarch
, python_language
);
242 if (evregpy_no_listeners_p (gdb_py_events
.new_inferior
))
245 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
248 gdbpy_print_stack ();
252 gdbpy_ref
<> event
= create_event_object (&new_inferior_event_object_type
);
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
263 python_inferior_deleted (struct inferior
*inf
)
265 if (!gdb_python_initialized
)
268 gdbpy_enter
enter_py (python_gdbarch
, python_language
);
270 if (evregpy_no_listeners_p (gdb_py_events
.inferior_deleted
))
273 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
276 gdbpy_print_stack ();
280 gdbpy_ref
<> event
= create_event_object (&inferior_deleted_event_object_type
);
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 ();
289 thread_to_thread_object (thread_info
*thr
)
291 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (thr
->inf
);
295 for (threadlist_entry
*thread
= inf_obj
->threads
;
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"));
307 add_thread_object (struct thread_info
*tp
)
309 inferior_object
*inf_obj
;
310 struct threadlist_entry
*entry
;
312 if (!gdb_python_initialized
)
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 ();
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
;
332 if (evregpy_no_listeners_p (gdb_py_events
.new_thread
))
335 gdbpy_ref
<> event
= create_thread_event_object (&new_thread_event_object_type
,
336 (PyObject
*) inf_obj
);
338 || evpy_emit_event (event
.get (), gdb_py_events
.new_thread
) < 0)
339 gdbpy_print_stack ();
343 delete_thread_object (struct thread_info
*tp
, int ignore
)
345 struct threadlist_entry
**entry
, *tmp
;
347 if (!gdb_python_initialized
)
350 gdbpy_enter
enter_py (python_gdbarch
, python_language
);
352 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (tp
->inf
);
356 /* Find thread entry in its inferior's thread_list. */
357 for (entry
= &inf_obj
->threads
; *entry
!= NULL
; entry
=
359 if ((*entry
)->thread_obj
->thread
== tp
)
366 tmp
->thread_obj
->thread
= NULL
;
368 *entry
= (*entry
)->next
;
375 infpy_threads (PyObject
*self
, PyObject
*args
)
378 struct threadlist_entry
*entry
;
379 inferior_object
*inf_obj
= (inferior_object
*) self
;
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
);
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 ();
402 PyTuple_SET_ITEM (tuple
, i
, thr
);
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. */
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. */
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)
446 return gdb_py_object_from_longest (target
->connection_number
).release ();
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 ();
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
)
470 /* Getter of gdb.Inferior.progspace. */
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. */
488 gdbpy_inferiors (PyObject
*unused
, PyObject
*unused2
)
490 gdbpy_ref
<> list (PyList_New (0));
494 for (inferior
*inf
: all_inferiors ())
496 gdbpy_ref
<inferior_object
> inferior
= inferior_to_inferior_object (inf
);
498 if (inferior
== NULL
)
501 if (PyList_Append (list
.get (), (PyObject
*) inferior
.get ()) != 0)
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. */
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
))
526 if (get_addr_from_python (addr_obj
, &addr
) < 0
527 || get_addr_from_python (length_obj
, &length
) < 0)
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. */
552 infpy_write_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
554 struct gdb_exception except
;
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
};
562 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "Os*|O", keywords
,
563 &addr_obj
, &pybuf
, &length_obj
))
566 Py_buffer_up
buffer_up (&pybuf
);
567 buffer
= (const gdb_byte
*) pybuf
.buf
;
570 if (get_addr_from_python (addr_obj
, &addr
) < 0)
575 else if (get_addr_from_python (length_obj
, &length
) < 0)
580 write_memory_with_notification (addr
, buffer
, length
);
582 catch (gdb_exception
&ex
)
584 except
= std::move (ex
);
587 GDB_PY_HANDLE_EXCEPTION (except
);
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. */
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
;
613 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OOs*", keywords
,
614 &start_addr_obj
, &length_obj
,
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)
625 if (get_addr_from_python (length_obj
, &length
) < 0)
630 PyErr_SetString (PyExc_ValueError
,
631 _("Search range is empty."));
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."));
645 found
= target_search_memory (start_addr
, length
,
646 buffer
, pattern_size
,
649 catch (gdb_exception
&ex
)
651 except
= std::move (ex
);
654 GDB_PY_HANDLE_EXCEPTION (except
);
657 return gdb_py_object_from_ulongest (found_addr
).release ();
662 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
663 Returns True if this inferior object still exists in GDB. */
666 infpy_is_valid (PyObject
*self
, PyObject
*args
)
668 inferior_object
*inf
= (inferior_object
*) self
;
676 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
677 -> gdb.InferiorThread. */
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
))
691 const gdb_byte
*bytes
;
693 Py_buffer_up buffer_up
;
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
));
711 PyErr_SetString (PyExc_TypeError
,
712 _("Argument 'handle' must be a thread handle object."));
719 struct thread_info
*thread_info
;
721 thread_info
= find_thread_by_handle
722 (gdb::array_view
<const gdb_byte
> (bytes
, bytes_len
),
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
);
735 /* Implementation of gdb.Inferior.architecture. */
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. */
750 infpy_repr (PyObject
*obj
)
752 inferior_object
*self
= (inferior_object
*) obj
;
753 inferior
*inf
= self
->inferior
;
756 return PyString_FromString ("<gdb.Inferior (invalid)>");
758 return PyString_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
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
787 py_free_inferior (struct inferior
*inf
, void *datum
)
789 struct threadlist_entry
*th_entry
, *th_tmp
;
791 if (!gdb_python_initialized
)
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
;)
803 th_entry
= th_entry
->next
;
807 inf_obj
->nthreads
= 0;
810 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
811 Returns the current inferior object. */
814 gdbpy_selected_inferior (PyObject
*self
, PyObject
*args
)
817 inferior_to_inferior_object (current_inferior ()).release ());
820 void _initialize_py_inferior ();
822 _initialize_py_inferior ()
825 register_inferior_data_with_cleanup (NULL
, py_free_inferior
);
829 gdbpy_initialize_inferior (void)
831 if (PyType_Ready (&inferior_object_type
) < 0)
834 if (gdb_pymodule_addobject (gdb_module
, "Inferior",
835 (PyObject
*) &inferior_object_type
) < 0)
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
,
844 gdb::observers::inferior_call_post
.attach (python_on_inferior_call_post
,
846 gdb::observers::memory_changed
.attach (python_on_memory_change
,
848 gdb::observers::register_changed
.attach (python_on_register_change
,
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
,
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.",
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" },
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." },
913 PyTypeObject inferior_object_type
=
915 PyVarObject_HEAD_INIT (NULL
, 0)
916 "gdb.Inferior", /* tp_name */
917 sizeof (inferior_object
), /* tp_basicsize */
919 infpy_dealloc
, /* tp_dealloc */
924 infpy_repr
, /* tp_repr */
925 0, /* tp_as_number */
926 0, /* tp_as_sequence */
927 0, /* tp_as_mapping */
933 0, /* tp_as_buffer */
934 Py_TPFLAGS_DEFAULT
, /* tp_flags */
935 "GDB inferior object", /* tp_doc */
938 0, /* tp_richcompare */
939 0, /* tp_weaklistoffset */
942 inferior_object_methods
, /* tp_methods */
944 inferior_object_getset
, /* tp_getset */
947 0, /* tp_descr_get */
948 0, /* tp_descr_set */
949 0, /* tp_dictoffset */