1 /* Python interface to inferiors.
3 Copyright (C) 2009-2023 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"
33 #include "progspace-and-thread.h"
34 #include <unordered_map>
37 = std::unordered_map
<thread_info
*, gdbpy_ref
<thread_object
>>;
39 struct inferior_object
43 /* The inferior we represent. */
44 struct inferior
*inferior
;
46 /* thread_object instances under this inferior. This owns a
47 reference to each object it contains. */
48 thread_map_t
*threads
;
51 extern PyTypeObject inferior_object_type
52 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
54 /* Deleter to clean up when an inferior is removed. */
57 void operator() (inferior_object
*obj
)
59 if (!gdb_python_initialized
)
63 gdbpy_ref
<inferior_object
> inf_obj (obj
);
65 inf_obj
->inferior
= NULL
;
67 delete inf_obj
->threads
;
71 static const registry
<inferior
>::key
<inferior_object
, infpy_deleter
>
74 /* Require that INFERIOR be a valid inferior ID. */
75 #define INFPY_REQUIRE_VALID(Inferior) \
77 if (!Inferior->inferior) \
79 PyErr_SetString (PyExc_RuntimeError, \
80 _("Inferior no longer exists.")); \
86 python_on_normal_stop (struct bpstat
*bs
, int print_frame
)
88 enum gdb_signal stop_signal
;
90 if (!gdb_python_initialized
)
93 if (inferior_ptid
== null_ptid
)
96 stop_signal
= inferior_thread ()->stop_signal ();
100 if (emit_stop_event (bs
, stop_signal
) < 0)
101 gdbpy_print_stack ();
105 python_on_resume (ptid_t ptid
)
107 if (!gdb_python_initialized
)
110 gdbpy_enter
enter_py (current_inferior ()->arch ());
112 if (emit_continue_event (ptid
) < 0)
113 gdbpy_print_stack ();
116 /* Callback, registered as an observer, that notifies Python listeners
117 when an inferior function call is about to be made. */
120 python_on_inferior_call_pre (ptid_t thread
, CORE_ADDR address
)
122 gdbpy_enter
enter_py (current_inferior ()->arch ());
124 if (emit_inferior_call_event (INFERIOR_CALL_PRE
, thread
, address
) < 0)
125 gdbpy_print_stack ();
128 /* Callback, registered as an observer, that notifies Python listeners
129 when an inferior function call has completed. */
132 python_on_inferior_call_post (ptid_t thread
, CORE_ADDR address
)
134 gdbpy_enter
enter_py (current_inferior ()->arch ());
136 if (emit_inferior_call_event (INFERIOR_CALL_POST
, thread
, address
) < 0)
137 gdbpy_print_stack ();
140 /* Callback, registered as an observer, that notifies Python listeners
141 when a part of memory has been modified by user action (eg via a
145 python_on_memory_change (struct inferior
*inferior
, CORE_ADDR addr
, ssize_t len
, const bfd_byte
*data
)
147 gdbpy_enter
enter_py (current_inferior ()->arch ());
149 if (emit_memory_changed_event (addr
, len
) < 0)
150 gdbpy_print_stack ();
153 /* Callback, registered as an observer, that notifies Python listeners
154 when a register has been modified by user action (eg via a 'set'
158 python_on_register_change (frame_info_ptr frame
, int regnum
)
160 gdbpy_enter
enter_py (current_inferior ()->arch ());
162 if (emit_register_changed_event (frame
, regnum
) < 0)
163 gdbpy_print_stack ();
167 python_inferior_exit (struct inferior
*inf
)
169 const LONGEST
*exit_code
= NULL
;
171 if (!gdb_python_initialized
)
174 gdbpy_enter
enter_py (current_inferior ()->arch ());
176 if (inf
->has_exit_code
)
177 exit_code
= &inf
->exit_code
;
179 if (emit_exited_event (exit_code
, inf
) < 0)
180 gdbpy_print_stack ();
183 /* Callback used to notify Python listeners about new objfiles loaded in the
184 inferior. OBJFILE may be NULL which means that the objfile list has been
185 cleared (emptied). */
188 python_new_objfile (struct objfile
*objfile
)
190 if (!gdb_python_initialized
)
193 gdbpy_enter
enter_py (objfile
->arch ());
195 if (emit_new_objfile_event (objfile
) < 0)
196 gdbpy_print_stack ();
200 python_all_objfiles_removed (program_space
*pspace
)
202 if (!gdb_python_initialized
)
205 gdbpy_enter
enter_py (current_inferior ()->arch ());
207 if (emit_clear_objfiles_event (pspace
) < 0)
208 gdbpy_print_stack ();
211 /* Emit a Python event when an objfile is about to be removed. */
214 python_free_objfile (struct objfile
*objfile
)
216 if (!gdb_python_initialized
)
219 gdbpy_enter
enter_py (objfile
->arch ());
221 if (emit_free_objfile_event (objfile
) < 0)
222 gdbpy_print_stack ();
225 /* Return a reference to the Python object of type Inferior
226 representing INFERIOR. If the object has already been created,
227 return it and increment the reference count, otherwise, create it.
228 Return NULL on failure. */
230 gdbpy_ref
<inferior_object
>
231 inferior_to_inferior_object (struct inferior
*inferior
)
233 inferior_object
*inf_obj
;
235 inf_obj
= infpy_inf_data_key
.get (inferior
);
238 inf_obj
= PyObject_New (inferior_object
, &inferior_object_type
);
242 inf_obj
->inferior
= inferior
;
243 inf_obj
->threads
= new thread_map_t ();
245 /* PyObject_New initializes the new object with a refcount of 1. This
246 counts for the reference we are keeping in the inferior data. */
247 infpy_inf_data_key
.set (inferior
, inf_obj
);
250 /* We are returning a new reference. */
251 gdb_assert (inf_obj
!= nullptr);
252 return gdbpy_ref
<inferior_object
>::new_reference (inf_obj
);
255 /* Called when a new inferior is created. Notifies any Python event
258 python_new_inferior (struct inferior
*inf
)
260 if (!gdb_python_initialized
)
263 gdbpy_enter enter_py
;
265 if (evregpy_no_listeners_p (gdb_py_events
.new_inferior
))
268 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
271 gdbpy_print_stack ();
275 gdbpy_ref
<> event
= create_event_object (&new_inferior_event_object_type
);
277 || evpy_add_attribute (event
.get (), "inferior",
278 (PyObject
*) inf_obj
.get ()) < 0
279 || evpy_emit_event (event
.get (), gdb_py_events
.new_inferior
) < 0)
280 gdbpy_print_stack ();
283 /* Called when an inferior is removed. Notifies any Python event
286 python_inferior_deleted (struct inferior
*inf
)
288 if (!gdb_python_initialized
)
291 gdbpy_enter enter_py
;
293 if (evregpy_no_listeners_p (gdb_py_events
.inferior_deleted
))
296 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
299 gdbpy_print_stack ();
303 gdbpy_ref
<> event
= create_event_object (&inferior_deleted_event_object_type
);
305 || evpy_add_attribute (event
.get (), "inferior",
306 (PyObject
*) inf_obj
.get ()) < 0
307 || evpy_emit_event (event
.get (), gdb_py_events
.inferior_deleted
) < 0)
308 gdbpy_print_stack ();
312 thread_to_thread_object (thread_info
*thr
)
314 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (thr
->inf
);
318 auto thread_it
= inf_obj
->threads
->find (thr
);
319 if (thread_it
!= inf_obj
->threads
->end ())
320 return gdbpy_ref
<>::new_reference
321 ((PyObject
*) (thread_it
->second
.get ()));
323 PyErr_SetString (PyExc_SystemError
,
324 _("could not find gdb thread object"));
329 add_thread_object (struct thread_info
*tp
)
331 inferior_object
*inf_obj
;
333 if (!gdb_python_initialized
)
336 gdbpy_enter enter_py
;
338 gdbpy_ref
<thread_object
> thread_obj
= create_thread_object (tp
);
339 if (thread_obj
== NULL
)
341 gdbpy_print_stack ();
345 inf_obj
= (inferior_object
*) thread_obj
->inf_obj
;
347 auto ins_result
= inf_obj
->threads
->emplace
348 (thread_map_t::value_type (tp
, std::move (thread_obj
)));
350 if (!ins_result
.second
)
353 if (evregpy_no_listeners_p (gdb_py_events
.new_thread
))
356 gdbpy_ref
<> event
= create_thread_event_object
357 (&new_thread_event_object_type
,
358 (PyObject
*) ins_result
.first
->second
.get ());
361 || evpy_emit_event (event
.get (), gdb_py_events
.new_thread
) < 0)
362 gdbpy_print_stack ();
366 delete_thread_object (thread_info
*tp
,
367 gdb::optional
<ULONGEST
> /* exit_code */,
370 if (!gdb_python_initialized
)
373 gdbpy_enter enter_py
;
375 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (tp
->inf
);
379 if (emit_thread_exit_event (tp
) < 0)
380 gdbpy_print_stack ();
382 auto it
= inf_obj
->threads
->find (tp
);
383 if (it
!= inf_obj
->threads
->end ())
385 /* Some python code can still hold a reference to the thread_object
386 instance. Make sure to remove the link to the associated
387 thread_info object as it will be freed soon. This makes the python
388 object invalid (i.e. gdb.InfThread.is_valid returns False). */
389 it
->second
->thread
= nullptr;
390 inf_obj
->threads
->erase (it
);
395 infpy_threads (PyObject
*self
, PyObject
*args
)
398 inferior_object
*inf_obj
= (inferior_object
*) self
;
401 INFPY_REQUIRE_VALID (inf_obj
);
405 update_thread_list ();
407 catch (const gdb_exception
&except
)
409 GDB_PY_HANDLE_EXCEPTION (except
);
412 tuple
= PyTuple_New (inf_obj
->threads
->size ());
416 for (const thread_map_t::value_type
&entry
: *inf_obj
->threads
)
418 PyObject
*thr
= (PyObject
*) entry
.second
.get ();
420 PyTuple_SET_ITEM (tuple
, i
, thr
);
428 infpy_get_num (PyObject
*self
, void *closure
)
430 inferior_object
*inf
= (inferior_object
*) self
;
432 INFPY_REQUIRE_VALID (inf
);
434 return gdb_py_object_from_longest (inf
->inferior
->num
).release ();
437 /* Return the gdb.TargetConnection object for this inferior, or None if a
438 connection does not exist. */
441 infpy_get_connection (PyObject
*self
, void *closure
)
443 inferior_object
*inf
= (inferior_object
*) self
;
445 INFPY_REQUIRE_VALID (inf
);
447 process_stratum_target
*target
= inf
->inferior
->process_target ();
448 return target_to_connection_object (target
).release ();
451 /* Return the connection number of the given inferior, or None if a
452 connection does not exist. */
455 infpy_get_connection_num (PyObject
*self
, void *closure
)
457 inferior_object
*inf
= (inferior_object
*) self
;
459 INFPY_REQUIRE_VALID (inf
);
461 process_stratum_target
*target
= inf
->inferior
->process_target ();
462 if (target
== nullptr)
465 return gdb_py_object_from_longest (target
->connection_number
).release ();
469 infpy_get_pid (PyObject
*self
, void *closure
)
471 inferior_object
*inf
= (inferior_object
*) self
;
473 INFPY_REQUIRE_VALID (inf
);
475 return gdb_py_object_from_longest (inf
->inferior
->pid
).release ();
479 infpy_get_was_attached (PyObject
*self
, void *closure
)
481 inferior_object
*inf
= (inferior_object
*) self
;
483 INFPY_REQUIRE_VALID (inf
);
484 if (inf
->inferior
->attach_flag
)
489 /* Getter of gdb.Inferior.progspace. */
492 infpy_get_progspace (PyObject
*self
, void *closure
)
494 inferior_object
*inf
= (inferior_object
*) self
;
496 INFPY_REQUIRE_VALID (inf
);
498 program_space
*pspace
= inf
->inferior
->pspace
;
499 gdb_assert (pspace
!= nullptr);
501 return pspace_to_pspace_object (pspace
).release ();
504 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
505 Returns a tuple of all inferiors. */
507 gdbpy_inferiors (PyObject
*unused
, PyObject
*unused2
)
509 gdbpy_ref
<> list (PyList_New (0));
513 for (inferior
*inf
: all_inferiors ())
515 gdbpy_ref
<inferior_object
> inferior
= inferior_to_inferior_object (inf
);
517 if (inferior
== NULL
)
520 if (PyList_Append (list
.get (), (PyObject
*) inferior
.get ()) != 0)
524 return PyList_AsTuple (list
.get ());
527 /* Membuf and memory manipulation. */
529 /* Implementation of Inferior.read_memory (address, length).
530 Returns a Python buffer object with LENGTH bytes of the inferior's
531 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
532 with a python exception set. */
534 infpy_read_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
536 inferior_object
*inf
= (inferior_object
*) self
;
537 CORE_ADDR addr
, length
;
538 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer
;
539 PyObject
*addr_obj
, *length_obj
;
540 static const char *keywords
[] = { "address", "length", NULL
};
542 INFPY_REQUIRE_VALID (inf
);
544 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OO", keywords
,
545 &addr_obj
, &length_obj
))
548 if (get_addr_from_python (addr_obj
, &addr
) < 0
549 || get_addr_from_python (length_obj
, &length
) < 0)
554 /* Use this scoped-restore because we want to be able to read
555 memory from an unwinder. */
556 scoped_restore_current_inferior_for_memory restore_inferior
559 buffer
.reset ((gdb_byte
*) xmalloc (length
));
561 read_memory (addr
, buffer
.get (), length
);
563 catch (const gdb_exception
&except
)
565 GDB_PY_HANDLE_EXCEPTION (except
);
569 return gdbpy_buffer_to_membuf (std::move (buffer
), addr
, length
);
572 /* Implementation of Inferior.write_memory (address, buffer [, length]).
573 Writes the contents of BUFFER (a Python object supporting the read
574 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
575 bytes from BUFFER, or its entire contents if the argument is not
576 provided. The function returns nothing. Returns NULL on error, with
577 a python exception set. */
579 infpy_write_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
581 inferior_object
*inf
= (inferior_object
*) self
;
582 struct gdb_exception except
;
584 const gdb_byte
*buffer
;
585 CORE_ADDR addr
, length
;
586 PyObject
*addr_obj
, *length_obj
= NULL
;
587 static const char *keywords
[] = { "address", "buffer", "length", NULL
};
590 INFPY_REQUIRE_VALID (inf
);
592 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "Os*|O", keywords
,
593 &addr_obj
, &pybuf
, &length_obj
))
596 Py_buffer_up
buffer_up (&pybuf
);
597 buffer
= (const gdb_byte
*) pybuf
.buf
;
600 if (get_addr_from_python (addr_obj
, &addr
) < 0)
605 else if (get_addr_from_python (length_obj
, &length
) < 0)
610 /* It's probably not too important to avoid invalidating the
611 frame cache when writing memory, but this scoped-restore is
612 still used here, just to keep the code similar to other code
614 scoped_restore_current_inferior_for_memory restore_inferior
617 write_memory_with_notification (addr
, buffer
, length
);
619 catch (gdb_exception
&ex
)
621 except
= std::move (ex
);
624 GDB_PY_HANDLE_EXCEPTION (except
);
630 Inferior.search_memory (address, length, pattern). ADDRESS is the
631 address to start the search. LENGTH specifies the scope of the
632 search from ADDRESS. PATTERN is the pattern to search for (and
633 must be a Python object supporting the buffer protocol).
634 Returns a Python Long object holding the address where the pattern
635 was located, or if the pattern was not found, returns None. Returns NULL
636 on error, with a python exception set. */
638 infpy_search_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
640 inferior_object
*inf
= (inferior_object
*) self
;
641 struct gdb_exception except
;
642 CORE_ADDR start_addr
, length
;
643 static const char *keywords
[] = { "address", "length", "pattern", NULL
};
644 PyObject
*start_addr_obj
, *length_obj
;
645 Py_ssize_t pattern_size
;
646 const gdb_byte
*buffer
;
647 CORE_ADDR found_addr
;
651 INFPY_REQUIRE_VALID (inf
);
653 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OOs*", keywords
,
654 &start_addr_obj
, &length_obj
,
658 Py_buffer_up
buffer_up (&pybuf
);
659 buffer
= (const gdb_byte
*) pybuf
.buf
;
660 pattern_size
= pybuf
.len
;
662 if (get_addr_from_python (start_addr_obj
, &start_addr
) < 0)
665 if (get_addr_from_python (length_obj
, &length
) < 0)
670 PyErr_SetString (PyExc_ValueError
,
671 _("Search range is empty."));
674 /* Watch for overflows. */
675 else if (length
> CORE_ADDR_MAX
676 || (start_addr
+ length
- 1) < start_addr
)
678 PyErr_SetString (PyExc_ValueError
,
679 _("The search range is too large."));
685 /* It's probably not too important to avoid invalidating the
686 frame cache when searching memory, but this scoped-restore is
687 still used here, just to keep the code similar to other code
689 scoped_restore_current_inferior_for_memory restore_inferior
692 found
= target_search_memory (start_addr
, length
,
693 buffer
, pattern_size
,
696 catch (gdb_exception
&ex
)
698 except
= std::move (ex
);
701 GDB_PY_HANDLE_EXCEPTION (except
);
704 return gdb_py_object_from_ulongest (found_addr
).release ();
709 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
710 Returns True if this inferior object still exists in GDB. */
713 infpy_is_valid (PyObject
*self
, PyObject
*args
)
715 inferior_object
*inf
= (inferior_object
*) self
;
723 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
724 -> gdb.InferiorThread. */
727 infpy_thread_from_thread_handle (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
729 PyObject
*handle_obj
;
730 inferior_object
*inf_obj
= (inferior_object
*) self
;
731 static const char *keywords
[] = { "handle", NULL
};
733 INFPY_REQUIRE_VALID (inf_obj
);
735 if (! gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "O", keywords
, &handle_obj
))
738 const gdb_byte
*bytes
;
740 Py_buffer_up buffer_up
;
743 if (PyObject_CheckBuffer (handle_obj
)
744 && PyObject_GetBuffer (handle_obj
, &py_buf
, PyBUF_SIMPLE
) == 0)
746 buffer_up
.reset (&py_buf
);
747 bytes
= (const gdb_byte
*) py_buf
.buf
;
748 bytes_len
= py_buf
.len
;
750 else if (gdbpy_is_value_object (handle_obj
))
752 struct value
*val
= value_object_to_value (handle_obj
);
753 bytes
= val
->contents_all ().data ();
754 bytes_len
= val
->type ()->length ();
758 PyErr_SetString (PyExc_TypeError
,
759 _("Argument 'handle' must be a thread handle object."));
766 struct thread_info
*thread_info
;
768 thread_info
= find_thread_by_handle
769 (gdb::array_view
<const gdb_byte
> (bytes
, bytes_len
),
771 if (thread_info
!= NULL
)
772 return thread_to_thread_object (thread_info
).release ();
774 catch (const gdb_exception
&except
)
776 GDB_PY_HANDLE_EXCEPTION (except
);
782 /* Implementation of gdb.Inferior.architecture. */
785 infpy_architecture (PyObject
*self
, PyObject
*args
)
787 inferior_object
*inf
= (inferior_object
*) self
;
789 INFPY_REQUIRE_VALID (inf
);
791 return gdbarch_to_arch_object (inf
->inferior
->arch ());
794 /* Implement repr() for gdb.Inferior. */
797 infpy_repr (PyObject
*obj
)
799 inferior_object
*self
= (inferior_object
*) obj
;
800 inferior
*inf
= self
->inferior
;
803 return PyUnicode_FromString ("<gdb.Inferior (invalid)>");
805 return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
809 /* Implement clear_env. */
812 infpy_clear_env (PyObject
*obj
)
814 inferior_object
*self
= (inferior_object
*) obj
;
816 INFPY_REQUIRE_VALID (self
);
818 self
->inferior
->environment
.clear ();
822 /* Implement set_env. */
825 infpy_set_env (PyObject
*obj
, PyObject
*args
, PyObject
*kw
)
827 inferior_object
*self
= (inferior_object
*) obj
;
828 INFPY_REQUIRE_VALID (self
);
830 const char *name
, *val
;
831 static const char *keywords
[] = { "name", "value", nullptr };
833 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "ss", keywords
,
837 self
->inferior
->environment
.set (name
, val
);
841 /* Implement unset_env. */
844 infpy_unset_env (PyObject
*obj
, PyObject
*args
, PyObject
*kw
)
846 inferior_object
*self
= (inferior_object
*) obj
;
847 INFPY_REQUIRE_VALID (self
);
850 static const char *keywords
[] = { "name", nullptr };
851 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "s", keywords
, &name
))
854 self
->inferior
->environment
.unset (name
);
858 /* Getter for "arguments". */
861 infpy_get_args (PyObject
*self
, void *closure
)
863 inferior_object
*inf
= (inferior_object
*) self
;
865 INFPY_REQUIRE_VALID (inf
);
867 const std::string
&args
= inf
->inferior
->args ();
871 return host_string_to_python_string (args
.c_str ()).release ();
874 /* Setter for "arguments". */
877 infpy_set_args (PyObject
*self
, PyObject
*value
, void *closure
)
879 inferior_object
*inf
= (inferior_object
*) self
;
883 PyErr_SetString (PyExc_RuntimeError
, _("Inferior no longer exists."));
887 if (value
== nullptr)
889 PyErr_SetString (PyExc_TypeError
,
890 _("Cannot delete 'arguments' attribute."));
894 if (gdbpy_is_string (value
))
896 gdb::unique_xmalloc_ptr
<char> str
= python_string_to_host_string (value
);
899 inf
->inferior
->set_args (std::string (str
.get ()));
901 else if (PySequence_Check (value
))
903 std::vector
<gdb::unique_xmalloc_ptr
<char>> args
;
904 Py_ssize_t len
= PySequence_Size (value
);
907 for (Py_ssize_t i
= 0; i
< len
; ++i
)
909 gdbpy_ref
<> item (PySequence_ITEM (value
, i
));
912 gdb::unique_xmalloc_ptr
<char> str
913 = python_string_to_host_string (item
.get ());
916 args
.push_back (std::move (str
));
918 std::vector
<char *> argvec
;
919 for (const auto &arg
: args
)
920 argvec
.push_back (arg
.get ());
921 gdb::array_view
<char * const> view (argvec
.data (), argvec
.size ());
922 inf
->inferior
->set_args (view
);
926 PyErr_SetString (PyExc_TypeError
,
927 _("string or sequence required for 'arguments'"));
933 /* Getter for "main_name". */
936 infpy_get_main_name (PyObject
*self
, void *closure
)
938 inferior_object
*inf
= (inferior_object
*) self
;
940 INFPY_REQUIRE_VALID (inf
);
942 const char *name
= nullptr;
945 /* This is unfortunate but the implementation of main_name can
946 reach into memory. It's probably not too important to avoid
947 invalidating the frame cache here, but this scoped-restore is
948 still used, just to keep the code similar to other code in
950 scoped_restore_current_inferior_for_memory restore_inferior
955 catch (const gdb_exception
&except
)
957 /* We can just ignore this. */
963 return host_string_to_python_string (name
).release ();
967 infpy_dealloc (PyObject
*obj
)
969 inferior_object
*inf_obj
= (inferior_object
*) obj
;
971 /* The inferior itself holds a reference to this Python object, which
972 will keep the reference count of this object above zero until GDB
973 deletes the inferior and py_free_inferior is called.
975 Once py_free_inferior has been called then the link between this
976 Python object and the inferior is set to nullptr, and then the
977 reference count on this Python object is decremented.
979 The result of all this is that the link between this Python object and
980 the inferior should always have been set to nullptr before this
981 function is called. */
982 gdb_assert (inf_obj
->inferior
== nullptr);
984 Py_TYPE (obj
)->tp_free (obj
);
987 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
988 Returns the current inferior object. */
991 gdbpy_selected_inferior (PyObject
*self
, PyObject
*args
)
994 inferior_to_inferior_object (current_inferior ()).release ());
997 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
998 gdbpy_initialize_inferior (void)
1000 if (PyType_Ready (&inferior_object_type
) < 0)
1003 if (gdb_pymodule_addobject (gdb_module
, "Inferior",
1004 (PyObject
*) &inferior_object_type
) < 0)
1007 gdb::observers::new_thread
.attach (add_thread_object
, "py-inferior");
1008 gdb::observers::thread_exit
.attach (delete_thread_object
, "py-inferior");
1009 gdb::observers::normal_stop
.attach (python_on_normal_stop
, "py-inferior");
1010 gdb::observers::target_resumed
.attach (python_on_resume
, "py-inferior");
1011 gdb::observers::inferior_call_pre
.attach (python_on_inferior_call_pre
,
1013 gdb::observers::inferior_call_post
.attach (python_on_inferior_call_post
,
1015 gdb::observers::memory_changed
.attach (python_on_memory_change
,
1017 gdb::observers::register_changed
.attach (python_on_register_change
,
1019 gdb::observers::inferior_exit
.attach (python_inferior_exit
, "py-inferior");
1020 /* Need to run after auto-load's new_objfile observer, so that
1021 auto-loaded pretty-printers are available. */
1022 gdb::observers::new_objfile
.attach
1023 (python_new_objfile
, "py-inferior",
1024 { &auto_load_new_objfile_observer_token
});
1025 gdb::observers::all_objfiles_removed
.attach (python_all_objfiles_removed
,
1027 gdb::observers::free_objfile
.attach (python_free_objfile
, "py-inferior");
1028 gdb::observers::inferior_added
.attach (python_new_inferior
, "py-inferior");
1029 gdb::observers::inferior_removed
.attach (python_inferior_deleted
,
1035 GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior
);
1039 static gdb_PyGetSetDef inferior_object_getset
[] =
1041 { "arguments", infpy_get_args
, infpy_set_args
,
1042 "Arguments to this program.", nullptr },
1043 { "num", infpy_get_num
, NULL
, "ID of inferior, as assigned by GDB.", NULL
},
1044 { "connection", infpy_get_connection
, NULL
,
1045 "The gdb.TargetConnection for this inferior.", NULL
},
1046 { "connection_num", infpy_get_connection_num
, NULL
,
1047 "ID of inferior's connection, as assigned by GDB.", NULL
},
1048 { "pid", infpy_get_pid
, NULL
, "PID of inferior, as assigned by the OS.",
1050 { "was_attached", infpy_get_was_attached
, NULL
,
1051 "True if the inferior was created using 'attach'.", NULL
},
1052 { "progspace", infpy_get_progspace
, NULL
, "Program space of this inferior" },
1053 { "main_name", infpy_get_main_name
, nullptr,
1054 "Name of 'main' function, if known.", nullptr },
1058 static PyMethodDef inferior_object_methods
[] =
1060 { "is_valid", infpy_is_valid
, METH_NOARGS
,
1061 "is_valid () -> Boolean.\n\
1062 Return true if this inferior is valid, false if not." },
1063 { "threads", infpy_threads
, METH_NOARGS
,
1064 "Return all the threads of this inferior." },
1065 { "read_memory", (PyCFunction
) infpy_read_memory
,
1066 METH_VARARGS
| METH_KEYWORDS
,
1067 "read_memory (address, length) -> buffer\n\
1068 Return a buffer object for reading from the inferior's memory." },
1069 { "write_memory", (PyCFunction
) infpy_write_memory
,
1070 METH_VARARGS
| METH_KEYWORDS
,
1071 "write_memory (address, buffer [, length])\n\
1072 Write the given buffer object to the inferior's memory." },
1073 { "search_memory", (PyCFunction
) infpy_search_memory
,
1074 METH_VARARGS
| METH_KEYWORDS
,
1075 "search_memory (address, length, pattern) -> long\n\
1076 Return a long with the address of a match, or None." },
1077 /* thread_from_thread_handle is deprecated. */
1078 { "thread_from_thread_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
1079 METH_VARARGS
| METH_KEYWORDS
,
1080 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
1081 Return thread object corresponding to thread handle.\n\
1082 This method is deprecated - use thread_from_handle instead." },
1083 { "thread_from_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
1084 METH_VARARGS
| METH_KEYWORDS
,
1085 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
1086 Return thread object corresponding to thread handle." },
1087 { "architecture", (PyCFunction
) infpy_architecture
, METH_NOARGS
,
1088 "architecture () -> gdb.Architecture\n\
1089 Return architecture of this inferior." },
1090 { "clear_env", (PyCFunction
) infpy_clear_env
, METH_NOARGS
,
1091 "clear_env () -> None\n\
1092 Clear environment of this inferior." },
1093 { "set_env", (PyCFunction
) infpy_set_env
, METH_VARARGS
| METH_KEYWORDS
,
1094 "set_env (name, value) -> None\n\
1095 Set an environment variable of this inferior." },
1096 { "unset_env", (PyCFunction
) infpy_unset_env
, METH_VARARGS
| METH_KEYWORDS
,
1097 "unset_env (name) -> None\n\
1098 Unset an environment of this inferior." },
1102 PyTypeObject inferior_object_type
=
1104 PyVarObject_HEAD_INIT (NULL
, 0)
1105 "gdb.Inferior", /* tp_name */
1106 sizeof (inferior_object
), /* tp_basicsize */
1107 0, /* tp_itemsize */
1108 infpy_dealloc
, /* tp_dealloc */
1113 infpy_repr
, /* tp_repr */
1114 0, /* tp_as_number */
1115 0, /* tp_as_sequence */
1116 0, /* tp_as_mapping */
1120 0, /* tp_getattro */
1121 0, /* tp_setattro */
1122 0, /* tp_as_buffer */
1123 Py_TPFLAGS_DEFAULT
, /* tp_flags */
1124 "GDB inferior object", /* tp_doc */
1125 0, /* tp_traverse */
1127 0, /* tp_richcompare */
1128 0, /* tp_weaklistoffset */
1130 0, /* tp_iternext */
1131 inferior_object_methods
, /* tp_methods */
1133 inferior_object_getset
, /* tp_getset */
1136 0, /* tp_descr_get */
1137 0, /* tp_descr_set */
1138 0, /* tp_dictoffset */