1 /* Python interface to inferiors.
3 Copyright (C) 2009-2024 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
;
50 /* Dictionary holding user-added attributes.
51 This is the __dict__ attribute of the object. */
55 extern PyTypeObject inferior_object_type
56 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
58 /* Deleter to clean up when an inferior is removed. */
61 void operator() (inferior_object
*obj
)
63 if (!gdb_python_initialized
)
67 gdbpy_ref
<inferior_object
> inf_obj (obj
);
69 inf_obj
->inferior
= NULL
;
71 delete inf_obj
->threads
;
75 static const registry
<inferior
>::key
<inferior_object
, infpy_deleter
>
78 /* Require that INFERIOR be a valid inferior ID. */
79 #define INFPY_REQUIRE_VALID(Inferior) \
81 if (!Inferior->inferior) \
83 PyErr_SetString (PyExc_RuntimeError, \
84 _("Inferior no longer exists.")); \
90 python_on_normal_stop (struct bpstat
*bs
, int print_frame
)
92 enum gdb_signal stop_signal
;
94 if (!gdb_python_initialized
)
97 if (inferior_ptid
== null_ptid
)
100 stop_signal
= inferior_thread ()->stop_signal ();
102 gdbpy_enter enter_py
;
104 if (emit_stop_event (bs
, stop_signal
) < 0)
105 gdbpy_print_stack ();
109 python_on_resume (ptid_t ptid
)
111 if (!gdb_python_initialized
)
114 gdbpy_enter
enter_py (current_inferior ()->arch ());
116 if (emit_continue_event (ptid
) < 0)
117 gdbpy_print_stack ();
120 /* Callback, registered as an observer, that notifies Python listeners
121 when an inferior function call is about to be made. */
124 python_on_inferior_call_pre (ptid_t thread
, CORE_ADDR address
)
126 gdbpy_enter
enter_py (current_inferior ()->arch ());
128 if (emit_inferior_call_event (INFERIOR_CALL_PRE
, thread
, address
) < 0)
129 gdbpy_print_stack ();
132 /* Callback, registered as an observer, that notifies Python listeners
133 when an inferior function call has completed. */
136 python_on_inferior_call_post (ptid_t thread
, CORE_ADDR address
)
138 gdbpy_enter
enter_py (current_inferior ()->arch ());
140 if (emit_inferior_call_event (INFERIOR_CALL_POST
, thread
, address
) < 0)
141 gdbpy_print_stack ();
144 /* Callback, registered as an observer, that notifies Python listeners
145 when a part of memory has been modified by user action (eg via a
149 python_on_memory_change (struct inferior
*inferior
, CORE_ADDR addr
, ssize_t len
, const bfd_byte
*data
)
151 gdbpy_enter
enter_py (current_inferior ()->arch ());
153 if (emit_memory_changed_event (addr
, len
) < 0)
154 gdbpy_print_stack ();
157 /* Callback, registered as an observer, that notifies Python listeners
158 when a register has been modified by user action (eg via a 'set'
162 python_on_register_change (frame_info_ptr frame
, int regnum
)
164 gdbpy_enter
enter_py (current_inferior ()->arch ());
166 if (emit_register_changed_event (frame
, regnum
) < 0)
167 gdbpy_print_stack ();
171 python_inferior_exit (struct inferior
*inf
)
173 const LONGEST
*exit_code
= NULL
;
175 if (!gdb_python_initialized
)
178 gdbpy_enter
enter_py (current_inferior ()->arch ());
180 if (inf
->has_exit_code
)
181 exit_code
= &inf
->exit_code
;
183 if (emit_exited_event (exit_code
, inf
) < 0)
184 gdbpy_print_stack ();
187 /* Callback used to notify Python listeners about new objfiles loaded in the
188 inferior. OBJFILE may be NULL which means that the objfile list has been
189 cleared (emptied). */
192 python_new_objfile (struct objfile
*objfile
)
194 if (!gdb_python_initialized
)
197 gdbpy_enter
enter_py (objfile
->arch ());
199 if (emit_new_objfile_event (objfile
) < 0)
200 gdbpy_print_stack ();
204 python_all_objfiles_removed (program_space
*pspace
)
206 if (!gdb_python_initialized
)
209 gdbpy_enter
enter_py (current_inferior ()->arch ());
211 if (emit_clear_objfiles_event (pspace
) < 0)
212 gdbpy_print_stack ();
215 /* Emit a Python event when an objfile is about to be removed. */
218 python_free_objfile (struct objfile
*objfile
)
220 if (!gdb_python_initialized
)
223 gdbpy_enter
enter_py (objfile
->arch ());
225 if (emit_free_objfile_event (objfile
) < 0)
226 gdbpy_print_stack ();
229 /* Return a reference to the Python object of type Inferior
230 representing INFERIOR. If the object has already been created,
231 return it and increment the reference count, otherwise, create it.
232 Return NULL on failure. */
234 gdbpy_ref
<inferior_object
>
235 inferior_to_inferior_object (struct inferior
*inferior
)
237 inferior_object
*inf_obj
;
239 inf_obj
= infpy_inf_data_key
.get (inferior
);
242 inf_obj
= PyObject_New (inferior_object
, &inferior_object_type
);
246 inf_obj
->inferior
= inferior
;
247 inf_obj
->threads
= new thread_map_t ();
248 inf_obj
->dict
= PyDict_New ();
249 if (inf_obj
->dict
== nullptr)
252 /* PyObject_New initializes the new object with a refcount of 1. This
253 counts for the reference we are keeping in the inferior data. */
254 infpy_inf_data_key
.set (inferior
, inf_obj
);
257 /* We are returning a new reference. */
258 gdb_assert (inf_obj
!= nullptr);
259 return gdbpy_ref
<inferior_object
>::new_reference (inf_obj
);
262 /* Called when a new inferior is created. Notifies any Python event
265 python_new_inferior (struct inferior
*inf
)
267 if (!gdb_python_initialized
)
270 gdbpy_enter enter_py
;
272 if (evregpy_no_listeners_p (gdb_py_events
.new_inferior
))
275 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
278 gdbpy_print_stack ();
282 gdbpy_ref
<> event
= create_event_object (&new_inferior_event_object_type
);
284 || evpy_add_attribute (event
.get (), "inferior",
285 (PyObject
*) inf_obj
.get ()) < 0
286 || evpy_emit_event (event
.get (), gdb_py_events
.new_inferior
) < 0)
287 gdbpy_print_stack ();
290 /* Called when an inferior is removed. Notifies any Python event
293 python_inferior_deleted (struct inferior
*inf
)
295 if (!gdb_python_initialized
)
298 gdbpy_enter enter_py
;
300 if (evregpy_no_listeners_p (gdb_py_events
.inferior_deleted
))
303 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
306 gdbpy_print_stack ();
310 gdbpy_ref
<> event
= create_event_object (&inferior_deleted_event_object_type
);
312 || evpy_add_attribute (event
.get (), "inferior",
313 (PyObject
*) inf_obj
.get ()) < 0
314 || evpy_emit_event (event
.get (), gdb_py_events
.inferior_deleted
) < 0)
315 gdbpy_print_stack ();
319 thread_to_thread_object (thread_info
*thr
)
321 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (thr
->inf
);
325 auto thread_it
= inf_obj
->threads
->find (thr
);
326 if (thread_it
!= inf_obj
->threads
->end ())
327 return gdbpy_ref
<>::new_reference
328 ((PyObject
*) (thread_it
->second
.get ()));
330 PyErr_SetString (PyExc_SystemError
,
331 _("could not find gdb thread object"));
336 add_thread_object (struct thread_info
*tp
)
338 inferior_object
*inf_obj
;
340 if (!gdb_python_initialized
)
343 gdbpy_enter enter_py
;
345 gdbpy_ref
<thread_object
> thread_obj
= create_thread_object (tp
);
346 if (thread_obj
== NULL
)
348 gdbpy_print_stack ();
352 inf_obj
= (inferior_object
*) thread_obj
->inf_obj
;
354 auto ins_result
= inf_obj
->threads
->emplace
355 (thread_map_t::value_type (tp
, std::move (thread_obj
)));
357 if (!ins_result
.second
)
360 if (evregpy_no_listeners_p (gdb_py_events
.new_thread
))
363 gdbpy_ref
<> event
= create_thread_event_object
364 (&new_thread_event_object_type
,
365 (PyObject
*) ins_result
.first
->second
.get ());
368 || evpy_emit_event (event
.get (), gdb_py_events
.new_thread
) < 0)
369 gdbpy_print_stack ();
373 delete_thread_object (thread_info
*tp
,
374 std::optional
<ULONGEST
> /* exit_code */,
377 if (!gdb_python_initialized
)
380 gdbpy_enter enter_py
;
382 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (tp
->inf
);
386 if (emit_thread_exit_event (tp
) < 0)
387 gdbpy_print_stack ();
389 auto it
= inf_obj
->threads
->find (tp
);
390 if (it
!= inf_obj
->threads
->end ())
392 /* Some python code can still hold a reference to the thread_object
393 instance. Make sure to remove the link to the associated
394 thread_info object as it will be freed soon. This makes the python
395 object invalid (i.e. gdb.InfThread.is_valid returns False). */
396 it
->second
->thread
= nullptr;
397 inf_obj
->threads
->erase (it
);
402 infpy_threads (PyObject
*self
, PyObject
*args
)
405 inferior_object
*inf_obj
= (inferior_object
*) self
;
408 INFPY_REQUIRE_VALID (inf_obj
);
412 update_thread_list ();
414 catch (const gdb_exception
&except
)
416 GDB_PY_HANDLE_EXCEPTION (except
);
419 tuple
= PyTuple_New (inf_obj
->threads
->size ());
423 for (const thread_map_t::value_type
&entry
: *inf_obj
->threads
)
425 PyObject
*thr
= (PyObject
*) entry
.second
.get ();
427 PyTuple_SET_ITEM (tuple
, i
, thr
);
435 infpy_get_num (PyObject
*self
, void *closure
)
437 inferior_object
*inf
= (inferior_object
*) self
;
439 INFPY_REQUIRE_VALID (inf
);
441 return gdb_py_object_from_longest (inf
->inferior
->num
).release ();
444 /* Return the gdb.TargetConnection object for this inferior, or None if a
445 connection does not exist. */
448 infpy_get_connection (PyObject
*self
, void *closure
)
450 inferior_object
*inf
= (inferior_object
*) self
;
452 INFPY_REQUIRE_VALID (inf
);
454 process_stratum_target
*target
= inf
->inferior
->process_target ();
455 return target_to_connection_object (target
).release ();
458 /* Return the connection number of the given inferior, or None if a
459 connection does not exist. */
462 infpy_get_connection_num (PyObject
*self
, void *closure
)
464 inferior_object
*inf
= (inferior_object
*) self
;
466 INFPY_REQUIRE_VALID (inf
);
468 process_stratum_target
*target
= inf
->inferior
->process_target ();
469 if (target
== nullptr)
472 return gdb_py_object_from_longest (target
->connection_number
).release ();
476 infpy_get_pid (PyObject
*self
, void *closure
)
478 inferior_object
*inf
= (inferior_object
*) self
;
480 INFPY_REQUIRE_VALID (inf
);
482 return gdb_py_object_from_longest (inf
->inferior
->pid
).release ();
486 infpy_get_was_attached (PyObject
*self
, void *closure
)
488 inferior_object
*inf
= (inferior_object
*) self
;
490 INFPY_REQUIRE_VALID (inf
);
491 if (inf
->inferior
->attach_flag
)
496 /* Getter of gdb.Inferior.progspace. */
499 infpy_get_progspace (PyObject
*self
, void *closure
)
501 inferior_object
*inf
= (inferior_object
*) self
;
503 INFPY_REQUIRE_VALID (inf
);
505 program_space
*pspace
= inf
->inferior
->pspace
;
506 gdb_assert (pspace
!= nullptr);
508 return pspace_to_pspace_object (pspace
).release ();
511 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
512 Returns a tuple of all inferiors. */
514 gdbpy_inferiors (PyObject
*unused
, PyObject
*unused2
)
516 gdbpy_ref
<> list (PyList_New (0));
520 for (inferior
*inf
: all_inferiors ())
522 gdbpy_ref
<inferior_object
> inferior
= inferior_to_inferior_object (inf
);
524 if (inferior
== NULL
)
527 if (PyList_Append (list
.get (), (PyObject
*) inferior
.get ()) != 0)
531 return PyList_AsTuple (list
.get ());
534 /* Membuf and memory manipulation. */
536 /* Implementation of Inferior.read_memory (address, length).
537 Returns a Python buffer object with LENGTH bytes of the inferior's
538 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
539 with a python exception set. */
541 infpy_read_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
543 inferior_object
*inf
= (inferior_object
*) self
;
544 CORE_ADDR addr
, length
;
545 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer
;
546 PyObject
*addr_obj
, *length_obj
;
547 static const char *keywords
[] = { "address", "length", NULL
};
549 INFPY_REQUIRE_VALID (inf
);
551 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OO", keywords
,
552 &addr_obj
, &length_obj
))
555 if (get_addr_from_python (addr_obj
, &addr
) < 0
556 || get_addr_from_python (length_obj
, &length
) < 0)
561 /* Use this scoped-restore because we want to be able to read
562 memory from an unwinder. */
563 scoped_restore_current_inferior_for_memory restore_inferior
566 buffer
.reset ((gdb_byte
*) xmalloc (length
));
568 read_memory (addr
, buffer
.get (), length
);
570 catch (const gdb_exception
&except
)
572 GDB_PY_HANDLE_EXCEPTION (except
);
576 return gdbpy_buffer_to_membuf (std::move (buffer
), addr
, length
);
579 /* Implementation of Inferior.write_memory (address, buffer [, length]).
580 Writes the contents of BUFFER (a Python object supporting the read
581 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
582 bytes from BUFFER, or its entire contents if the argument is not
583 provided. The function returns nothing. Returns NULL on error, with
584 a python exception set. */
586 infpy_write_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
588 inferior_object
*inf
= (inferior_object
*) self
;
589 struct gdb_exception except
;
591 const gdb_byte
*buffer
;
592 CORE_ADDR addr
, length
;
593 PyObject
*addr_obj
, *length_obj
= NULL
;
594 static const char *keywords
[] = { "address", "buffer", "length", NULL
};
597 INFPY_REQUIRE_VALID (inf
);
599 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "Os*|O", keywords
,
600 &addr_obj
, &pybuf
, &length_obj
))
603 Py_buffer_up
buffer_up (&pybuf
);
604 buffer
= (const gdb_byte
*) pybuf
.buf
;
607 if (get_addr_from_python (addr_obj
, &addr
) < 0)
612 else if (get_addr_from_python (length_obj
, &length
) < 0)
617 /* It's probably not too important to avoid invalidating the
618 frame cache when writing memory, but this scoped-restore is
619 still used here, just to keep the code similar to other code
621 scoped_restore_current_inferior_for_memory restore_inferior
624 write_memory_with_notification (addr
, buffer
, length
);
626 catch (gdb_exception
&ex
)
628 except
= std::move (ex
);
631 GDB_PY_HANDLE_EXCEPTION (except
);
637 Inferior.search_memory (address, length, pattern). ADDRESS is the
638 address to start the search. LENGTH specifies the scope of the
639 search from ADDRESS. PATTERN is the pattern to search for (and
640 must be a Python object supporting the buffer protocol).
641 Returns a Python Long object holding the address where the pattern
642 was located, or if the pattern was not found, returns None. Returns NULL
643 on error, with a python exception set. */
645 infpy_search_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
647 inferior_object
*inf
= (inferior_object
*) self
;
648 struct gdb_exception except
;
649 CORE_ADDR start_addr
, length
;
650 static const char *keywords
[] = { "address", "length", "pattern", NULL
};
651 PyObject
*start_addr_obj
, *length_obj
;
652 Py_ssize_t pattern_size
;
653 const gdb_byte
*buffer
;
654 CORE_ADDR found_addr
;
658 INFPY_REQUIRE_VALID (inf
);
660 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OOs*", keywords
,
661 &start_addr_obj
, &length_obj
,
665 Py_buffer_up
buffer_up (&pybuf
);
666 buffer
= (const gdb_byte
*) pybuf
.buf
;
667 pattern_size
= pybuf
.len
;
669 if (get_addr_from_python (start_addr_obj
, &start_addr
) < 0)
672 if (get_addr_from_python (length_obj
, &length
) < 0)
677 PyErr_SetString (PyExc_ValueError
,
678 _("Search range is empty."));
681 /* Watch for overflows. */
682 else if (length
> CORE_ADDR_MAX
683 || (start_addr
+ length
- 1) < start_addr
)
685 PyErr_SetString (PyExc_ValueError
,
686 _("The search range is too large."));
692 /* It's probably not too important to avoid invalidating the
693 frame cache when searching memory, but this scoped-restore is
694 still used here, just to keep the code similar to other code
696 scoped_restore_current_inferior_for_memory restore_inferior
699 found
= target_search_memory (start_addr
, length
,
700 buffer
, pattern_size
,
703 catch (gdb_exception
&ex
)
705 except
= std::move (ex
);
708 GDB_PY_HANDLE_EXCEPTION (except
);
711 return gdb_py_object_from_ulongest (found_addr
).release ();
716 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
717 Returns True if this inferior object still exists in GDB. */
720 infpy_is_valid (PyObject
*self
, PyObject
*args
)
722 inferior_object
*inf
= (inferior_object
*) self
;
730 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
731 -> gdb.InferiorThread. */
734 infpy_thread_from_thread_handle (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
736 PyObject
*handle_obj
;
737 inferior_object
*inf_obj
= (inferior_object
*) self
;
738 static const char *keywords
[] = { "handle", NULL
};
740 INFPY_REQUIRE_VALID (inf_obj
);
742 if (! gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "O", keywords
, &handle_obj
))
745 const gdb_byte
*bytes
;
747 Py_buffer_up buffer_up
;
750 if (PyObject_CheckBuffer (handle_obj
)
751 && PyObject_GetBuffer (handle_obj
, &py_buf
, PyBUF_SIMPLE
) == 0)
753 buffer_up
.reset (&py_buf
);
754 bytes
= (const gdb_byte
*) py_buf
.buf
;
755 bytes_len
= py_buf
.len
;
757 else if (gdbpy_is_value_object (handle_obj
))
759 struct value
*val
= value_object_to_value (handle_obj
);
760 bytes
= val
->contents_all ().data ();
761 bytes_len
= val
->type ()->length ();
765 PyErr_SetString (PyExc_TypeError
,
766 _("Argument 'handle' must be a thread handle object."));
773 struct thread_info
*thread_info
;
775 thread_info
= find_thread_by_handle
776 (gdb::array_view
<const gdb_byte
> (bytes
, bytes_len
),
778 if (thread_info
!= NULL
)
779 return thread_to_thread_object (thread_info
).release ();
781 catch (const gdb_exception
&except
)
783 GDB_PY_HANDLE_EXCEPTION (except
);
789 /* Implementation of gdb.Inferior.architecture. */
792 infpy_architecture (PyObject
*self
, PyObject
*args
)
794 inferior_object
*inf
= (inferior_object
*) self
;
796 INFPY_REQUIRE_VALID (inf
);
798 return gdbarch_to_arch_object (inf
->inferior
->arch ());
801 /* Implement repr() for gdb.Inferior. */
804 infpy_repr (PyObject
*obj
)
806 inferior_object
*self
= (inferior_object
*) obj
;
807 inferior
*inf
= self
->inferior
;
810 return gdb_py_invalid_object_repr (obj
);
812 return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
816 /* Implement clear_env. */
819 infpy_clear_env (PyObject
*obj
)
821 inferior_object
*self
= (inferior_object
*) obj
;
823 INFPY_REQUIRE_VALID (self
);
825 self
->inferior
->environment
.clear ();
829 /* Implement set_env. */
832 infpy_set_env (PyObject
*obj
, PyObject
*args
, PyObject
*kw
)
834 inferior_object
*self
= (inferior_object
*) obj
;
835 INFPY_REQUIRE_VALID (self
);
837 const char *name
, *val
;
838 static const char *keywords
[] = { "name", "value", nullptr };
840 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "ss", keywords
,
844 self
->inferior
->environment
.set (name
, val
);
848 /* Implement unset_env. */
851 infpy_unset_env (PyObject
*obj
, PyObject
*args
, PyObject
*kw
)
853 inferior_object
*self
= (inferior_object
*) obj
;
854 INFPY_REQUIRE_VALID (self
);
857 static const char *keywords
[] = { "name", nullptr };
858 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "s", keywords
, &name
))
861 self
->inferior
->environment
.unset (name
);
865 /* Getter for "arguments". */
868 infpy_get_args (PyObject
*self
, void *closure
)
870 inferior_object
*inf
= (inferior_object
*) self
;
872 INFPY_REQUIRE_VALID (inf
);
874 const std::string
&args
= inf
->inferior
->args ();
878 return host_string_to_python_string (args
.c_str ()).release ();
881 /* Setter for "arguments". */
884 infpy_set_args (PyObject
*self
, PyObject
*value
, void *closure
)
886 inferior_object
*inf
= (inferior_object
*) self
;
890 PyErr_SetString (PyExc_RuntimeError
, _("Inferior no longer exists."));
894 if (value
== nullptr)
896 PyErr_SetString (PyExc_TypeError
,
897 _("Cannot delete 'arguments' attribute."));
901 if (gdbpy_is_string (value
))
903 gdb::unique_xmalloc_ptr
<char> str
= python_string_to_host_string (value
);
906 inf
->inferior
->set_args (std::string (str
.get ()));
908 else if (PySequence_Check (value
))
910 std::vector
<gdb::unique_xmalloc_ptr
<char>> args
;
911 Py_ssize_t len
= PySequence_Size (value
);
914 for (Py_ssize_t i
= 0; i
< len
; ++i
)
916 gdbpy_ref
<> item (PySequence_ITEM (value
, i
));
919 gdb::unique_xmalloc_ptr
<char> str
920 = python_string_to_host_string (item
.get ());
923 args
.push_back (std::move (str
));
925 std::vector
<char *> argvec
;
926 for (const auto &arg
: args
)
927 argvec
.push_back (arg
.get ());
928 gdb::array_view
<char * const> view (argvec
.data (), argvec
.size ());
929 inf
->inferior
->set_args (view
);
933 PyErr_SetString (PyExc_TypeError
,
934 _("string or sequence required for 'arguments'"));
940 /* Getter for "main_name". */
943 infpy_get_main_name (PyObject
*self
, void *closure
)
945 inferior_object
*inf
= (inferior_object
*) self
;
947 INFPY_REQUIRE_VALID (inf
);
949 const char *name
= nullptr;
952 /* This is unfortunate but the implementation of main_name can
953 reach into memory. It's probably not too important to avoid
954 invalidating the frame cache here, but this scoped-restore is
955 still used, just to keep the code similar to other code in
957 scoped_restore_current_inferior_for_memory restore_inferior
962 catch (const gdb_exception
&except
)
964 /* We can just ignore this. */
970 return host_string_to_python_string (name
).release ();
974 infpy_dealloc (PyObject
*obj
)
976 inferior_object
*inf_obj
= (inferior_object
*) obj
;
978 /* The inferior itself holds a reference to this Python object, which
979 will keep the reference count of this object above zero until GDB
980 deletes the inferior and py_free_inferior is called.
982 Once py_free_inferior has been called then the link between this
983 Python object and the inferior is set to nullptr, and then the
984 reference count on this Python object is decremented.
986 The result of all this is that the link between this Python object and
987 the inferior should always have been set to nullptr before this
988 function is called. */
989 gdb_assert (inf_obj
->inferior
== nullptr);
991 Py_XDECREF (inf_obj
->dict
);
993 Py_TYPE (obj
)->tp_free (obj
);
996 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
997 Returns the current inferior object. */
1000 gdbpy_selected_inferior (PyObject
*self
, PyObject
*args
)
1002 return ((PyObject
*)
1003 inferior_to_inferior_object (current_inferior ()).release ());
1006 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
1007 gdbpy_initialize_inferior (void)
1009 if (PyType_Ready (&inferior_object_type
) < 0)
1012 if (gdb_pymodule_addobject (gdb_module
, "Inferior",
1013 (PyObject
*) &inferior_object_type
) < 0)
1016 gdb::observers::new_thread
.attach (add_thread_object
, "py-inferior");
1017 gdb::observers::thread_exit
.attach (delete_thread_object
, "py-inferior");
1018 gdb::observers::normal_stop
.attach (python_on_normal_stop
, "py-inferior");
1019 gdb::observers::target_resumed
.attach (python_on_resume
, "py-inferior");
1020 gdb::observers::inferior_call_pre
.attach (python_on_inferior_call_pre
,
1022 gdb::observers::inferior_call_post
.attach (python_on_inferior_call_post
,
1024 gdb::observers::memory_changed
.attach (python_on_memory_change
,
1026 gdb::observers::register_changed
.attach (python_on_register_change
,
1028 gdb::observers::inferior_exit
.attach (python_inferior_exit
, "py-inferior");
1029 /* Need to run after auto-load's new_objfile observer, so that
1030 auto-loaded pretty-printers are available. */
1031 gdb::observers::new_objfile
.attach
1032 (python_new_objfile
, "py-inferior",
1033 { &auto_load_new_objfile_observer_token
});
1034 gdb::observers::all_objfiles_removed
.attach (python_all_objfiles_removed
,
1036 gdb::observers::free_objfile
.attach (python_free_objfile
, "py-inferior");
1037 gdb::observers::inferior_added
.attach (python_new_inferior
, "py-inferior");
1038 gdb::observers::inferior_removed
.attach (python_inferior_deleted
,
1044 GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior
);
1048 static gdb_PyGetSetDef inferior_object_getset
[] =
1050 { "__dict__", gdb_py_generic_dict
, nullptr,
1051 "The __dict__ for this inferior.", &inferior_object_type
},
1052 { "arguments", infpy_get_args
, infpy_set_args
,
1053 "Arguments to this program.", nullptr },
1054 { "num", infpy_get_num
, NULL
, "ID of inferior, as assigned by GDB.", NULL
},
1055 { "connection", infpy_get_connection
, NULL
,
1056 "The gdb.TargetConnection for this inferior.", NULL
},
1057 { "connection_num", infpy_get_connection_num
, NULL
,
1058 "ID of inferior's connection, as assigned by GDB.", NULL
},
1059 { "pid", infpy_get_pid
, NULL
, "PID of inferior, as assigned by the OS.",
1061 { "was_attached", infpy_get_was_attached
, NULL
,
1062 "True if the inferior was created using 'attach'.", NULL
},
1063 { "progspace", infpy_get_progspace
, NULL
, "Program space of this inferior" },
1064 { "main_name", infpy_get_main_name
, nullptr,
1065 "Name of 'main' function, if known.", nullptr },
1069 static PyMethodDef inferior_object_methods
[] =
1071 { "is_valid", infpy_is_valid
, METH_NOARGS
,
1072 "is_valid () -> Boolean.\n\
1073 Return true if this inferior is valid, false if not." },
1074 { "threads", infpy_threads
, METH_NOARGS
,
1075 "Return all the threads of this inferior." },
1076 { "read_memory", (PyCFunction
) infpy_read_memory
,
1077 METH_VARARGS
| METH_KEYWORDS
,
1078 "read_memory (address, length) -> buffer\n\
1079 Return a buffer object for reading from the inferior's memory." },
1080 { "write_memory", (PyCFunction
) infpy_write_memory
,
1081 METH_VARARGS
| METH_KEYWORDS
,
1082 "write_memory (address, buffer [, length])\n\
1083 Write the given buffer object to the inferior's memory." },
1084 { "search_memory", (PyCFunction
) infpy_search_memory
,
1085 METH_VARARGS
| METH_KEYWORDS
,
1086 "search_memory (address, length, pattern) -> long\n\
1087 Return a long with the address of a match, or None." },
1088 /* thread_from_thread_handle is deprecated. */
1089 { "thread_from_thread_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
1090 METH_VARARGS
| METH_KEYWORDS
,
1091 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
1092 Return thread object corresponding to thread handle.\n\
1093 This method is deprecated - use thread_from_handle instead." },
1094 { "thread_from_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
1095 METH_VARARGS
| METH_KEYWORDS
,
1096 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
1097 Return thread object corresponding to thread handle." },
1098 { "architecture", (PyCFunction
) infpy_architecture
, METH_NOARGS
,
1099 "architecture () -> gdb.Architecture\n\
1100 Return architecture of this inferior." },
1101 { "clear_env", (PyCFunction
) infpy_clear_env
, METH_NOARGS
,
1102 "clear_env () -> None\n\
1103 Clear environment of this inferior." },
1104 { "set_env", (PyCFunction
) infpy_set_env
, METH_VARARGS
| METH_KEYWORDS
,
1105 "set_env (name, value) -> None\n\
1106 Set an environment variable of this inferior." },
1107 { "unset_env", (PyCFunction
) infpy_unset_env
, METH_VARARGS
| METH_KEYWORDS
,
1108 "unset_env (name) -> None\n\
1109 Unset an environment of this inferior." },
1113 PyTypeObject inferior_object_type
=
1115 PyVarObject_HEAD_INIT (NULL
, 0)
1116 "gdb.Inferior", /* tp_name */
1117 sizeof (inferior_object
), /* tp_basicsize */
1118 0, /* tp_itemsize */
1119 infpy_dealloc
, /* tp_dealloc */
1124 infpy_repr
, /* tp_repr */
1125 0, /* tp_as_number */
1126 0, /* tp_as_sequence */
1127 0, /* tp_as_mapping */
1131 0, /* tp_getattro */
1132 0, /* tp_setattro */
1133 0, /* tp_as_buffer */
1134 Py_TPFLAGS_DEFAULT
, /* tp_flags */
1135 "GDB inferior object", /* tp_doc */
1136 0, /* tp_traverse */
1138 0, /* tp_richcompare */
1139 0, /* tp_weaklistoffset */
1141 0, /* tp_iternext */
1142 inferior_object_methods
, /* tp_methods */
1144 inferior_object_getset
, /* tp_getset */
1147 0, /* tp_descr_get */
1148 0, /* tp_descr_set */
1149 offsetof (inferior_object
, dict
), /* tp_dictoffset */