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
,
337 entry
->thread_obj
.get ());
339 || evpy_emit_event (event
.get (), gdb_py_events
.new_thread
) < 0)
340 gdbpy_print_stack ();
344 delete_thread_object (struct thread_info
*tp
, int ignore
)
346 struct threadlist_entry
**entry
, *tmp
;
348 if (!gdb_python_initialized
)
351 gdbpy_enter
enter_py (python_gdbarch
, python_language
);
353 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (tp
->inf
);
357 /* Find thread entry in its inferior's thread_list. */
358 for (entry
= &inf_obj
->threads
; *entry
!= NULL
; entry
=
360 if ((*entry
)->thread_obj
->thread
== tp
)
367 tmp
->thread_obj
->thread
= NULL
;
369 *entry
= (*entry
)->next
;
376 infpy_threads (PyObject
*self
, PyObject
*args
)
379 struct threadlist_entry
*entry
;
380 inferior_object
*inf_obj
= (inferior_object
*) self
;
383 INFPY_REQUIRE_VALID (inf_obj
);
387 update_thread_list ();
389 catch (const gdb_exception
&except
)
391 GDB_PY_HANDLE_EXCEPTION (except
);
394 tuple
= PyTuple_New (inf_obj
->nthreads
);
398 for (i
= 0, entry
= inf_obj
->threads
; i
< inf_obj
->nthreads
;
399 i
++, entry
= entry
->next
)
401 PyObject
*thr
= (PyObject
*) entry
->thread_obj
.get ();
403 PyTuple_SET_ITEM (tuple
, i
, thr
);
410 infpy_get_num (PyObject
*self
, void *closure
)
412 inferior_object
*inf
= (inferior_object
*) self
;
414 INFPY_REQUIRE_VALID (inf
);
416 return gdb_py_object_from_longest (inf
->inferior
->num
).release ();
419 /* Return the gdb.TargetConnection object for this inferior, or None if a
420 connection does not exist. */
423 infpy_get_connection (PyObject
*self
, void *closure
)
425 inferior_object
*inf
= (inferior_object
*) self
;
427 INFPY_REQUIRE_VALID (inf
);
429 process_stratum_target
*target
= inf
->inferior
->process_target ();
430 return target_to_connection_object (target
).release ();
433 /* Return the connection number of the given inferior, or None if a
434 connection does not exist. */
437 infpy_get_connection_num (PyObject
*self
, void *closure
)
439 inferior_object
*inf
= (inferior_object
*) self
;
441 INFPY_REQUIRE_VALID (inf
);
443 process_stratum_target
*target
= inf
->inferior
->process_target ();
444 if (target
== nullptr)
447 return gdb_py_object_from_longest (target
->connection_number
).release ();
451 infpy_get_pid (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
->pid
).release ();
461 infpy_get_was_attached (PyObject
*self
, void *closure
)
463 inferior_object
*inf
= (inferior_object
*) self
;
465 INFPY_REQUIRE_VALID (inf
);
466 if (inf
->inferior
->attach_flag
)
471 /* Getter of gdb.Inferior.progspace. */
474 infpy_get_progspace (PyObject
*self
, void *closure
)
476 inferior_object
*inf
= (inferior_object
*) self
;
478 INFPY_REQUIRE_VALID (inf
);
480 program_space
*pspace
= inf
->inferior
->pspace
;
481 gdb_assert (pspace
!= nullptr);
483 return pspace_to_pspace_object (pspace
).release ();
486 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
487 Returns a tuple of all inferiors. */
489 gdbpy_inferiors (PyObject
*unused
, PyObject
*unused2
)
491 gdbpy_ref
<> list (PyList_New (0));
495 for (inferior
*inf
: all_inferiors ())
497 gdbpy_ref
<inferior_object
> inferior
= inferior_to_inferior_object (inf
);
499 if (inferior
== NULL
)
502 if (PyList_Append (list
.get (), (PyObject
*) inferior
.get ()) != 0)
506 return PyList_AsTuple (list
.get ());
509 /* Membuf and memory manipulation. */
511 /* Implementation of Inferior.read_memory (address, length).
512 Returns a Python buffer object with LENGTH bytes of the inferior's
513 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
514 with a python exception set. */
516 infpy_read_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
518 CORE_ADDR addr
, length
;
519 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer
;
520 PyObject
*addr_obj
, *length_obj
;
521 static const char *keywords
[] = { "address", "length", NULL
};
523 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OO", keywords
,
524 &addr_obj
, &length_obj
))
527 if (get_addr_from_python (addr_obj
, &addr
) < 0
528 || get_addr_from_python (length_obj
, &length
) < 0)
533 buffer
.reset ((gdb_byte
*) xmalloc (length
));
535 read_memory (addr
, buffer
.get (), length
);
537 catch (const gdb_exception
&except
)
539 GDB_PY_HANDLE_EXCEPTION (except
);
543 return gdbpy_buffer_to_membuf (std::move (buffer
), addr
, length
);
546 /* Implementation of Inferior.write_memory (address, buffer [, length]).
547 Writes the contents of BUFFER (a Python object supporting the read
548 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
549 bytes from BUFFER, or its entire contents if the argument is not
550 provided. The function returns nothing. Returns NULL on error, with
551 a python exception set. */
553 infpy_write_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
555 struct gdb_exception except
;
557 const gdb_byte
*buffer
;
558 CORE_ADDR addr
, length
;
559 PyObject
*addr_obj
, *length_obj
= NULL
;
560 static const char *keywords
[] = { "address", "buffer", "length", NULL
};
563 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "Os*|O", keywords
,
564 &addr_obj
, &pybuf
, &length_obj
))
567 Py_buffer_up
buffer_up (&pybuf
);
568 buffer
= (const gdb_byte
*) pybuf
.buf
;
571 if (get_addr_from_python (addr_obj
, &addr
) < 0)
576 else if (get_addr_from_python (length_obj
, &length
) < 0)
581 write_memory_with_notification (addr
, buffer
, length
);
583 catch (gdb_exception
&ex
)
585 except
= std::move (ex
);
588 GDB_PY_HANDLE_EXCEPTION (except
);
594 gdb.search_memory (address, length, pattern). ADDRESS is the
595 address to start the search. LENGTH specifies the scope of the
596 search from ADDRESS. PATTERN is the pattern to search for (and
597 must be a Python object supporting the buffer protocol).
598 Returns a Python Long object holding the address where the pattern
599 was located, or if the pattern was not found, returns None. Returns NULL
600 on error, with a python exception set. */
602 infpy_search_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
604 struct gdb_exception except
;
605 CORE_ADDR start_addr
, length
;
606 static const char *keywords
[] = { "address", "length", "pattern", NULL
};
607 PyObject
*start_addr_obj
, *length_obj
;
608 Py_ssize_t pattern_size
;
609 const gdb_byte
*buffer
;
610 CORE_ADDR found_addr
;
614 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OOs*", keywords
,
615 &start_addr_obj
, &length_obj
,
619 Py_buffer_up
buffer_up (&pybuf
);
620 buffer
= (const gdb_byte
*) pybuf
.buf
;
621 pattern_size
= pybuf
.len
;
623 if (get_addr_from_python (start_addr_obj
, &start_addr
) < 0)
626 if (get_addr_from_python (length_obj
, &length
) < 0)
631 PyErr_SetString (PyExc_ValueError
,
632 _("Search range is empty."));
635 /* Watch for overflows. */
636 else if (length
> CORE_ADDR_MAX
637 || (start_addr
+ length
- 1) < start_addr
)
639 PyErr_SetString (PyExc_ValueError
,
640 _("The search range is too large."));
646 found
= target_search_memory (start_addr
, length
,
647 buffer
, pattern_size
,
650 catch (gdb_exception
&ex
)
652 except
= std::move (ex
);
655 GDB_PY_HANDLE_EXCEPTION (except
);
658 return gdb_py_object_from_ulongest (found_addr
).release ();
663 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
664 Returns True if this inferior object still exists in GDB. */
667 infpy_is_valid (PyObject
*self
, PyObject
*args
)
669 inferior_object
*inf
= (inferior_object
*) self
;
677 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
678 -> gdb.InferiorThread. */
681 infpy_thread_from_thread_handle (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
683 PyObject
*handle_obj
;
684 inferior_object
*inf_obj
= (inferior_object
*) self
;
685 static const char *keywords
[] = { "handle", NULL
};
687 INFPY_REQUIRE_VALID (inf_obj
);
689 if (! gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "O", keywords
, &handle_obj
))
692 const gdb_byte
*bytes
;
694 Py_buffer_up buffer_up
;
697 if (PyObject_CheckBuffer (handle_obj
)
698 && PyObject_GetBuffer (handle_obj
, &py_buf
, PyBUF_SIMPLE
) == 0)
700 buffer_up
.reset (&py_buf
);
701 bytes
= (const gdb_byte
*) py_buf
.buf
;
702 bytes_len
= py_buf
.len
;
704 else if (gdbpy_is_value_object (handle_obj
))
706 struct value
*val
= value_object_to_value (handle_obj
);
707 bytes
= value_contents_all (val
).data ();
708 bytes_len
= TYPE_LENGTH (value_type (val
));
712 PyErr_SetString (PyExc_TypeError
,
713 _("Argument 'handle' must be a thread handle object."));
720 struct thread_info
*thread_info
;
722 thread_info
= find_thread_by_handle
723 (gdb::array_view
<const gdb_byte
> (bytes
, bytes_len
),
725 if (thread_info
!= NULL
)
726 return thread_to_thread_object (thread_info
).release ();
728 catch (const gdb_exception
&except
)
730 GDB_PY_HANDLE_EXCEPTION (except
);
736 /* Implementation of gdb.Inferior.architecture. */
739 infpy_architecture (PyObject
*self
, PyObject
*args
)
741 inferior_object
*inf
= (inferior_object
*) self
;
743 INFPY_REQUIRE_VALID (inf
);
745 return gdbarch_to_arch_object (inf
->inferior
->gdbarch
);
748 /* Implement repr() for gdb.Inferior. */
751 infpy_repr (PyObject
*obj
)
753 inferior_object
*self
= (inferior_object
*) obj
;
754 inferior
*inf
= self
->inferior
;
757 return PyString_FromString ("<gdb.Inferior (invalid)>");
759 return PyString_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
765 infpy_dealloc (PyObject
*obj
)
767 inferior_object
*inf_obj
= (inferior_object
*) obj
;
769 /* The inferior itself holds a reference to this Python object, which
770 will keep the reference count of this object above zero until GDB
771 deletes the inferior and py_free_inferior is called.
773 Once py_free_inferior has been called then the link between this
774 Python object and the inferior is set to nullptr, and then the
775 reference count on this Python object is decremented.
777 The result of all this is that the link between this Python object and
778 the inferior should always have been set to nullptr before this
779 function is called. */
780 gdb_assert (inf_obj
->inferior
== nullptr);
782 Py_TYPE (obj
)->tp_free (obj
);
785 /* Clear the INFERIOR pointer in an Inferior object and clear the
788 py_free_inferior (struct inferior
*inf
, void *datum
)
790 struct threadlist_entry
*th_entry
, *th_tmp
;
792 if (!gdb_python_initialized
)
795 gdbpy_enter
enter_py (python_gdbarch
, python_language
);
796 gdbpy_ref
<inferior_object
> inf_obj ((inferior_object
*) datum
);
798 inf_obj
->inferior
= NULL
;
800 /* Deallocate threads list. */
801 for (th_entry
= inf_obj
->threads
; th_entry
!= NULL
;)
804 th_entry
= th_entry
->next
;
808 inf_obj
->nthreads
= 0;
811 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
812 Returns the current inferior object. */
815 gdbpy_selected_inferior (PyObject
*self
, PyObject
*args
)
818 inferior_to_inferior_object (current_inferior ()).release ());
821 void _initialize_py_inferior ();
823 _initialize_py_inferior ()
826 register_inferior_data_with_cleanup (NULL
, py_free_inferior
);
830 gdbpy_initialize_inferior (void)
832 if (PyType_Ready (&inferior_object_type
) < 0)
835 if (gdb_pymodule_addobject (gdb_module
, "Inferior",
836 (PyObject
*) &inferior_object_type
) < 0)
839 gdb::observers::new_thread
.attach (add_thread_object
, "py-inferior");
840 gdb::observers::thread_exit
.attach (delete_thread_object
, "py-inferior");
841 gdb::observers::normal_stop
.attach (python_on_normal_stop
, "py-inferior");
842 gdb::observers::target_resumed
.attach (python_on_resume
, "py-inferior");
843 gdb::observers::inferior_call_pre
.attach (python_on_inferior_call_pre
,
845 gdb::observers::inferior_call_post
.attach (python_on_inferior_call_post
,
847 gdb::observers::memory_changed
.attach (python_on_memory_change
,
849 gdb::observers::register_changed
.attach (python_on_register_change
,
851 gdb::observers::inferior_exit
.attach (python_inferior_exit
, "py-inferior");
852 /* Need to run after auto-load's new_objfile observer, so that
853 auto-loaded pretty-printers are available. */
854 gdb::observers::new_objfile
.attach
855 (python_new_objfile
, "py-inferior",
856 { &auto_load_new_objfile_observer_token
});
857 gdb::observers::inferior_added
.attach (python_new_inferior
, "py-inferior");
858 gdb::observers::inferior_removed
.attach (python_inferior_deleted
,
864 static gdb_PyGetSetDef inferior_object_getset
[] =
866 { "num", infpy_get_num
, NULL
, "ID of inferior, as assigned by GDB.", NULL
},
867 { "connection", infpy_get_connection
, NULL
,
868 "The gdb.TargetConnection for this inferior.", NULL
},
869 { "connection_num", infpy_get_connection_num
, NULL
,
870 "ID of inferior's connection, as assigned by GDB.", NULL
},
871 { "pid", infpy_get_pid
, NULL
, "PID of inferior, as assigned by the OS.",
873 { "was_attached", infpy_get_was_attached
, NULL
,
874 "True if the inferior was created using 'attach'.", NULL
},
875 { "progspace", infpy_get_progspace
, NULL
, "Program space of this inferior" },
879 static PyMethodDef inferior_object_methods
[] =
881 { "is_valid", infpy_is_valid
, METH_NOARGS
,
882 "is_valid () -> Boolean.\n\
883 Return true if this inferior is valid, false if not." },
884 { "threads", infpy_threads
, METH_NOARGS
,
885 "Return all the threads of this inferior." },
886 { "read_memory", (PyCFunction
) infpy_read_memory
,
887 METH_VARARGS
| METH_KEYWORDS
,
888 "read_memory (address, length) -> buffer\n\
889 Return a buffer object for reading from the inferior's memory." },
890 { "write_memory", (PyCFunction
) infpy_write_memory
,
891 METH_VARARGS
| METH_KEYWORDS
,
892 "write_memory (address, buffer [, length])\n\
893 Write the given buffer object to the inferior's memory." },
894 { "search_memory", (PyCFunction
) infpy_search_memory
,
895 METH_VARARGS
| METH_KEYWORDS
,
896 "search_memory (address, length, pattern) -> long\n\
897 Return a long with the address of a match, or None." },
898 /* thread_from_thread_handle is deprecated. */
899 { "thread_from_thread_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
900 METH_VARARGS
| METH_KEYWORDS
,
901 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
902 Return thread object corresponding to thread handle.\n\
903 This method is deprecated - use thread_from_handle instead." },
904 { "thread_from_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
905 METH_VARARGS
| METH_KEYWORDS
,
906 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
907 Return thread object corresponding to thread handle." },
908 { "architecture", (PyCFunction
) infpy_architecture
, METH_NOARGS
,
909 "architecture () -> gdb.Architecture\n\
910 Return architecture of this inferior." },
914 PyTypeObject inferior_object_type
=
916 PyVarObject_HEAD_INIT (NULL
, 0)
917 "gdb.Inferior", /* tp_name */
918 sizeof (inferior_object
), /* tp_basicsize */
920 infpy_dealloc
, /* tp_dealloc */
925 infpy_repr
, /* tp_repr */
926 0, /* tp_as_number */
927 0, /* tp_as_sequence */
928 0, /* tp_as_mapping */
934 0, /* tp_as_buffer */
935 Py_TPFLAGS_DEFAULT
, /* tp_flags */
936 "GDB inferior object", /* tp_doc */
939 0, /* tp_richcompare */
940 0, /* tp_weaklistoffset */
943 inferior_object_methods
, /* tp_methods */
945 inferior_object_getset
, /* tp_getset */
948 0, /* tp_descr_get */
949 0, /* tp_descr_set */
950 0, /* tp_dictoffset */