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/>. */
20 #include "auto-load.h"
22 #include "gdbthread.h"
25 #include "observable.h"
26 #include "python-internal.h"
27 #include "arch-utils.h"
29 #include "gdbsupport/gdb_signals.h"
31 #include "py-stopevent.h"
32 #include "progspace-and-thread.h"
33 #include <unordered_map>
36 = std::unordered_map
<thread_info
*, gdbpy_ref
<thread_object
>>;
38 struct inferior_object
42 /* The inferior we represent. */
43 struct inferior
*inferior
;
45 /* thread_object instances under this inferior. This owns a
46 reference to each object it contains. */
47 thread_map_t
*threads
;
49 /* Dictionary holding user-added attributes.
50 This is the __dict__ attribute of the object. */
54 extern PyTypeObject inferior_object_type
55 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
57 /* Deleter to clean up when an inferior is removed. */
60 void operator() (inferior_object
*obj
)
62 if (!gdb_python_initialized
)
66 gdbpy_ref
<inferior_object
> inf_obj (obj
);
68 inf_obj
->inferior
= NULL
;
70 delete inf_obj
->threads
;
74 static const registry
<inferior
>::key
<inferior_object
, infpy_deleter
>
77 /* Require that INFERIOR be a valid inferior ID. */
78 #define INFPY_REQUIRE_VALID(Inferior) \
80 if (!Inferior->inferior) \
82 PyErr_SetString (PyExc_RuntimeError, \
83 _("Inferior no longer exists.")); \
89 python_on_normal_stop (struct bpstat
*bs
, int print_frame
)
91 enum gdb_signal stop_signal
;
93 if (!gdb_python_initialized
)
96 if (inferior_ptid
== null_ptid
)
99 stop_signal
= inferior_thread ()->stop_signal ();
101 gdbpy_enter enter_py
;
103 if (emit_stop_event (bs
, stop_signal
) < 0)
104 gdbpy_print_stack ();
108 python_on_resume (ptid_t ptid
)
110 if (!gdb_python_initialized
)
113 gdbpy_enter
enter_py (current_inferior ()->arch ());
115 if (emit_continue_event (ptid
) < 0)
116 gdbpy_print_stack ();
119 /* Callback, registered as an observer, that notifies Python listeners
120 when an inferior function call is about to be made. */
123 python_on_inferior_call_pre (ptid_t thread
, CORE_ADDR address
)
125 gdbpy_enter
enter_py (current_inferior ()->arch ());
127 if (emit_inferior_call_event (INFERIOR_CALL_PRE
, thread
, address
) < 0)
128 gdbpy_print_stack ();
131 /* Callback, registered as an observer, that notifies Python listeners
132 when an inferior function call has completed. */
135 python_on_inferior_call_post (ptid_t thread
, CORE_ADDR address
)
137 gdbpy_enter
enter_py (current_inferior ()->arch ());
139 if (emit_inferior_call_event (INFERIOR_CALL_POST
, thread
, address
) < 0)
140 gdbpy_print_stack ();
143 /* Callback, registered as an observer, that notifies Python listeners
144 when a part of memory has been modified by user action (eg via a
148 python_on_memory_change (struct inferior
*inferior
, CORE_ADDR addr
, ssize_t len
, const bfd_byte
*data
)
150 gdbpy_enter
enter_py (current_inferior ()->arch ());
152 if (emit_memory_changed_event (addr
, len
) < 0)
153 gdbpy_print_stack ();
156 /* Callback, registered as an observer, that notifies Python listeners
157 when a register has been modified by user action (eg via a 'set'
161 python_on_register_change (const frame_info_ptr
&frame
, int regnum
)
163 gdbpy_enter
enter_py (current_inferior ()->arch ());
165 if (emit_register_changed_event (frame
, regnum
) < 0)
166 gdbpy_print_stack ();
170 python_inferior_exit (struct inferior
*inf
)
172 const LONGEST
*exit_code
= NULL
;
174 if (!gdb_python_initialized
)
177 gdbpy_enter
enter_py (current_inferior ()->arch ());
179 if (inf
->has_exit_code
)
180 exit_code
= &inf
->exit_code
;
182 if (emit_exited_event (exit_code
, inf
) < 0)
183 gdbpy_print_stack ();
186 /* Callback used to notify Python listeners about new objfiles loaded in the
187 inferior. OBJFILE may be NULL which means that the objfile list has been
188 cleared (emptied). */
191 python_new_objfile (struct objfile
*objfile
)
193 if (!gdb_python_initialized
)
196 gdbpy_enter
enter_py (objfile
->arch ());
198 if (emit_new_objfile_event (objfile
) < 0)
199 gdbpy_print_stack ();
203 python_all_objfiles_removed (program_space
*pspace
)
205 if (!gdb_python_initialized
)
208 gdbpy_enter
enter_py (current_inferior ()->arch ());
210 if (emit_clear_objfiles_event (pspace
) < 0)
211 gdbpy_print_stack ();
214 /* Emit a Python event when an objfile is about to be removed. */
217 python_free_objfile (struct objfile
*objfile
)
219 if (!gdb_python_initialized
)
222 gdbpy_enter
enter_py (objfile
->arch ());
224 if (emit_free_objfile_event (objfile
) < 0)
225 gdbpy_print_stack ();
228 /* Return a reference to the Python object of type Inferior
229 representing INFERIOR. If the object has already been created,
230 return it and increment the reference count, otherwise, create it.
231 Return NULL on failure. */
233 gdbpy_ref
<inferior_object
>
234 inferior_to_inferior_object (struct inferior
*inferior
)
236 inferior_object
*inf_obj
;
238 inf_obj
= infpy_inf_data_key
.get (inferior
);
241 inf_obj
= PyObject_New (inferior_object
, &inferior_object_type
);
245 inf_obj
->inferior
= inferior
;
246 inf_obj
->threads
= new thread_map_t ();
247 inf_obj
->dict
= PyDict_New ();
248 if (inf_obj
->dict
== nullptr)
251 /* PyObject_New initializes the new object with a refcount of 1. This
252 counts for the reference we are keeping in the inferior data. */
253 infpy_inf_data_key
.set (inferior
, inf_obj
);
256 /* We are returning a new reference. */
257 gdb_assert (inf_obj
!= nullptr);
258 return gdbpy_ref
<inferior_object
>::new_reference (inf_obj
);
261 /* Called when a new inferior is created. Notifies any Python event
264 python_new_inferior (struct inferior
*inf
)
266 if (!gdb_python_initialized
)
269 gdbpy_enter enter_py
;
271 if (evregpy_no_listeners_p (gdb_py_events
.new_inferior
))
274 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
277 gdbpy_print_stack ();
281 gdbpy_ref
<> event
= create_event_object (&new_inferior_event_object_type
);
283 || evpy_add_attribute (event
.get (), "inferior",
284 (PyObject
*) inf_obj
.get ()) < 0
285 || evpy_emit_event (event
.get (), gdb_py_events
.new_inferior
) < 0)
286 gdbpy_print_stack ();
289 /* Called when an inferior is removed. Notifies any Python event
292 python_inferior_deleted (struct inferior
*inf
)
294 if (!gdb_python_initialized
)
297 gdbpy_enter enter_py
;
299 if (evregpy_no_listeners_p (gdb_py_events
.inferior_deleted
))
302 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (inf
);
305 gdbpy_print_stack ();
309 gdbpy_ref
<> event
= create_event_object (&inferior_deleted_event_object_type
);
311 || evpy_add_attribute (event
.get (), "inferior",
312 (PyObject
*) inf_obj
.get ()) < 0
313 || evpy_emit_event (event
.get (), gdb_py_events
.inferior_deleted
) < 0)
314 gdbpy_print_stack ();
318 thread_to_thread_object (thread_info
*thr
)
320 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (thr
->inf
);
324 auto thread_it
= inf_obj
->threads
->find (thr
);
325 if (thread_it
!= inf_obj
->threads
->end ())
326 return gdbpy_ref
<>::new_reference
327 ((PyObject
*) (thread_it
->second
.get ()));
329 PyErr_SetString (PyExc_SystemError
,
330 _("could not find gdb thread object"));
335 add_thread_object (struct thread_info
*tp
)
337 inferior_object
*inf_obj
;
339 if (!gdb_python_initialized
)
342 gdbpy_enter enter_py
;
344 gdbpy_ref
<thread_object
> thread_obj
= create_thread_object (tp
);
345 if (thread_obj
== NULL
)
347 gdbpy_print_stack ();
351 inf_obj
= (inferior_object
*) thread_obj
->inf_obj
;
353 auto ins_result
= inf_obj
->threads
->emplace
354 (thread_map_t::value_type (tp
, std::move (thread_obj
)));
356 if (!ins_result
.second
)
359 if (evregpy_no_listeners_p (gdb_py_events
.new_thread
))
362 gdbpy_ref
<> event
= create_thread_event_object
363 (&new_thread_event_object_type
,
364 (PyObject
*) ins_result
.first
->second
.get ());
367 || evpy_emit_event (event
.get (), gdb_py_events
.new_thread
) < 0)
368 gdbpy_print_stack ();
372 delete_thread_object (thread_info
*tp
,
373 std::optional
<ULONGEST
> /* exit_code */,
376 if (!gdb_python_initialized
)
379 gdbpy_enter enter_py
;
381 gdbpy_ref
<inferior_object
> inf_obj
= inferior_to_inferior_object (tp
->inf
);
385 if (emit_thread_exit_event (tp
) < 0)
386 gdbpy_print_stack ();
388 auto it
= inf_obj
->threads
->find (tp
);
389 if (it
!= inf_obj
->threads
->end ())
391 /* Some python code can still hold a reference to the thread_object
392 instance. Make sure to remove the link to the associated
393 thread_info object as it will be freed soon. This makes the python
394 object invalid (i.e. gdb.InfThread.is_valid returns False). */
395 it
->second
->thread
= nullptr;
396 inf_obj
->threads
->erase (it
);
401 infpy_threads (PyObject
*self
, PyObject
*args
)
404 inferior_object
*inf_obj
= (inferior_object
*) self
;
407 INFPY_REQUIRE_VALID (inf_obj
);
411 update_thread_list ();
413 catch (const gdb_exception
&except
)
415 GDB_PY_HANDLE_EXCEPTION (except
);
418 tuple
= PyTuple_New (inf_obj
->threads
->size ());
422 for (const thread_map_t::value_type
&entry
: *inf_obj
->threads
)
424 PyObject
*thr
= (PyObject
*) entry
.second
.get ();
426 PyTuple_SET_ITEM (tuple
, i
, thr
);
434 infpy_get_num (PyObject
*self
, void *closure
)
436 inferior_object
*inf
= (inferior_object
*) self
;
438 INFPY_REQUIRE_VALID (inf
);
440 return gdb_py_object_from_longest (inf
->inferior
->num
).release ();
443 /* Return the gdb.TargetConnection object for this inferior, or None if a
444 connection does not exist. */
447 infpy_get_connection (PyObject
*self
, void *closure
)
449 inferior_object
*inf
= (inferior_object
*) self
;
451 INFPY_REQUIRE_VALID (inf
);
453 process_stratum_target
*target
= inf
->inferior
->process_target ();
454 return target_to_connection_object (target
).release ();
457 /* Return the connection number of the given inferior, or None if a
458 connection does not exist. */
461 infpy_get_connection_num (PyObject
*self
, void *closure
)
463 inferior_object
*inf
= (inferior_object
*) self
;
465 INFPY_REQUIRE_VALID (inf
);
467 process_stratum_target
*target
= inf
->inferior
->process_target ();
468 if (target
== nullptr)
471 return gdb_py_object_from_longest (target
->connection_number
).release ();
475 infpy_get_pid (PyObject
*self
, void *closure
)
477 inferior_object
*inf
= (inferior_object
*) self
;
479 INFPY_REQUIRE_VALID (inf
);
481 return gdb_py_object_from_longest (inf
->inferior
->pid
).release ();
485 infpy_get_was_attached (PyObject
*self
, void *closure
)
487 inferior_object
*inf
= (inferior_object
*) self
;
489 INFPY_REQUIRE_VALID (inf
);
490 if (inf
->inferior
->attach_flag
)
495 /* Getter of gdb.Inferior.progspace. */
498 infpy_get_progspace (PyObject
*self
, void *closure
)
500 inferior_object
*inf
= (inferior_object
*) self
;
502 INFPY_REQUIRE_VALID (inf
);
504 program_space
*pspace
= inf
->inferior
->pspace
;
505 gdb_assert (pspace
!= nullptr);
507 return pspace_to_pspace_object (pspace
).release ();
510 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
511 Returns a tuple of all inferiors. */
513 gdbpy_inferiors (PyObject
*unused
, PyObject
*unused2
)
515 gdbpy_ref
<> list (PyList_New (0));
519 for (inferior
*inf
: all_inferiors ())
521 gdbpy_ref
<inferior_object
> inferior
= inferior_to_inferior_object (inf
);
523 if (inferior
== NULL
)
526 if (PyList_Append (list
.get (), (PyObject
*) inferior
.get ()) != 0)
530 return PyList_AsTuple (list
.get ());
533 /* Membuf and memory manipulation. */
535 /* Implementation of Inferior.read_memory (address, length).
536 Returns a Python buffer object with LENGTH bytes of the inferior's
537 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
538 with a python exception set. */
540 infpy_read_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
542 inferior_object
*inf
= (inferior_object
*) self
;
543 CORE_ADDR addr
, length
;
544 gdb::unique_xmalloc_ptr
<gdb_byte
> buffer
;
545 PyObject
*addr_obj
, *length_obj
;
546 static const char *keywords
[] = { "address", "length", NULL
};
548 INFPY_REQUIRE_VALID (inf
);
550 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OO", keywords
,
551 &addr_obj
, &length_obj
))
554 if (get_addr_from_python (addr_obj
, &addr
) < 0
555 || get_addr_from_python (length_obj
, &length
) < 0)
560 PyErr_SetString (PyExc_ValueError
,
561 _("Argument 'count' should be greater than zero"));
565 void *p
= malloc (length
);
567 return PyErr_NoMemory ();
568 buffer
.reset ((gdb_byte
*) p
);
572 /* Use this scoped-restore because we want to be able to read
573 memory from an unwinder. */
574 scoped_restore_current_inferior_for_memory restore_inferior
577 read_memory (addr
, buffer
.get (), length
);
579 catch (const gdb_exception
&except
)
581 GDB_PY_HANDLE_EXCEPTION (except
);
585 return gdbpy_buffer_to_membuf (std::move (buffer
), addr
, length
);
588 /* Implementation of Inferior.write_memory (address, buffer [, length]).
589 Writes the contents of BUFFER (a Python object supporting the read
590 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
591 bytes from BUFFER, or its entire contents if the argument is not
592 provided. The function returns nothing. Returns NULL on error, with
593 a python exception set. */
595 infpy_write_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
597 inferior_object
*inf
= (inferior_object
*) self
;
599 const gdb_byte
*buffer
;
600 CORE_ADDR addr
, length
;
601 PyObject
*addr_obj
, *length_obj
= NULL
;
602 static const char *keywords
[] = { "address", "buffer", "length", NULL
};
605 INFPY_REQUIRE_VALID (inf
);
607 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "Os*|O", keywords
,
608 &addr_obj
, &pybuf
, &length_obj
))
611 Py_buffer_up
buffer_up (&pybuf
);
612 buffer
= (const gdb_byte
*) pybuf
.buf
;
615 if (get_addr_from_python (addr_obj
, &addr
) < 0)
620 else if (get_addr_from_python (length_obj
, &length
) < 0)
625 /* It's probably not too important to avoid invalidating the
626 frame cache when writing memory, but this scoped-restore is
627 still used here, just to keep the code similar to other code
629 scoped_restore_current_inferior_for_memory restore_inferior
632 write_memory_with_notification (addr
, buffer
, length
);
634 catch (gdb_exception
&ex
)
636 GDB_PY_HANDLE_EXCEPTION (ex
);
643 Inferior.search_memory (address, length, pattern). ADDRESS is the
644 address to start the search. LENGTH specifies the scope of the
645 search from ADDRESS. PATTERN is the pattern to search for (and
646 must be a Python object supporting the buffer protocol).
647 Returns a Python Long object holding the address where the pattern
648 was located, or if the pattern was not found, returns None. Returns NULL
649 on error, with a python exception set. */
651 infpy_search_memory (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
653 inferior_object
*inf
= (inferior_object
*) self
;
654 CORE_ADDR start_addr
, length
;
655 static const char *keywords
[] = { "address", "length", "pattern", NULL
};
656 PyObject
*start_addr_obj
, *length_obj
;
657 Py_ssize_t pattern_size
;
658 const gdb_byte
*buffer
;
659 CORE_ADDR found_addr
;
663 INFPY_REQUIRE_VALID (inf
);
665 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "OOs*", keywords
,
666 &start_addr_obj
, &length_obj
,
670 Py_buffer_up
buffer_up (&pybuf
);
671 buffer
= (const gdb_byte
*) pybuf
.buf
;
672 pattern_size
= pybuf
.len
;
674 if (get_addr_from_python (start_addr_obj
, &start_addr
) < 0)
677 if (get_addr_from_python (length_obj
, &length
) < 0)
682 PyErr_SetString (PyExc_ValueError
,
683 _("Search range is empty."));
686 /* Watch for overflows. */
687 else if (length
> CORE_ADDR_MAX
688 || (start_addr
+ length
- 1) < start_addr
)
690 PyErr_SetString (PyExc_ValueError
,
691 _("The search range is too large."));
697 /* It's probably not too important to avoid invalidating the
698 frame cache when searching memory, but this scoped-restore is
699 still used here, just to keep the code similar to other code
701 scoped_restore_current_inferior_for_memory restore_inferior
704 found
= target_search_memory (start_addr
, length
,
705 buffer
, pattern_size
,
708 catch (gdb_exception
&ex
)
710 GDB_PY_HANDLE_EXCEPTION (ex
);
714 return gdb_py_object_from_ulongest (found_addr
).release ();
719 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
720 Returns True if this inferior object still exists in GDB. */
723 infpy_is_valid (PyObject
*self
, PyObject
*args
)
725 inferior_object
*inf
= (inferior_object
*) self
;
733 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
734 -> gdb.InferiorThread. */
737 infpy_thread_from_thread_handle (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
739 PyObject
*handle_obj
;
740 inferior_object
*inf_obj
= (inferior_object
*) self
;
741 static const char *keywords
[] = { "handle", NULL
};
743 INFPY_REQUIRE_VALID (inf_obj
);
745 if (! gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "O", keywords
, &handle_obj
))
748 const gdb_byte
*bytes
;
750 Py_buffer_up buffer_up
;
753 if (PyObject_CheckBuffer (handle_obj
)
754 && PyObject_GetBuffer (handle_obj
, &py_buf
, PyBUF_SIMPLE
) == 0)
756 buffer_up
.reset (&py_buf
);
757 bytes
= (const gdb_byte
*) py_buf
.buf
;
758 bytes_len
= py_buf
.len
;
760 else if (gdbpy_is_value_object (handle_obj
))
762 struct value
*val
= value_object_to_value (handle_obj
);
763 bytes
= val
->contents_all ().data ();
764 bytes_len
= val
->type ()->length ();
768 PyErr_SetString (PyExc_TypeError
,
769 _("Argument 'handle' must be a thread handle object."));
776 struct thread_info
*thread_info
;
778 thread_info
= find_thread_by_handle
779 (gdb::array_view
<const gdb_byte
> (bytes
, bytes_len
),
781 if (thread_info
!= NULL
)
782 return thread_to_thread_object (thread_info
).release ();
784 catch (const gdb_exception
&except
)
786 GDB_PY_HANDLE_EXCEPTION (except
);
792 /* Implementation of gdb.Inferior.architecture. */
795 infpy_architecture (PyObject
*self
, PyObject
*args
)
797 inferior_object
*inf
= (inferior_object
*) self
;
799 INFPY_REQUIRE_VALID (inf
);
801 return gdbarch_to_arch_object (inf
->inferior
->arch ());
804 /* Implement repr() for gdb.Inferior. */
807 infpy_repr (PyObject
*obj
)
809 inferior_object
*self
= (inferior_object
*) obj
;
810 inferior
*inf
= self
->inferior
;
813 return gdb_py_invalid_object_repr (obj
);
815 return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
819 /* Implement clear_env. */
822 infpy_clear_env (PyObject
*obj
)
824 inferior_object
*self
= (inferior_object
*) obj
;
826 INFPY_REQUIRE_VALID (self
);
828 self
->inferior
->environment
.clear ();
832 /* Implement set_env. */
835 infpy_set_env (PyObject
*obj
, PyObject
*args
, PyObject
*kw
)
837 inferior_object
*self
= (inferior_object
*) obj
;
838 INFPY_REQUIRE_VALID (self
);
840 const char *name
, *val
;
841 static const char *keywords
[] = { "name", "value", nullptr };
843 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "ss", keywords
,
847 self
->inferior
->environment
.set (name
, val
);
851 /* Implement unset_env. */
854 infpy_unset_env (PyObject
*obj
, PyObject
*args
, PyObject
*kw
)
856 inferior_object
*self
= (inferior_object
*) obj
;
857 INFPY_REQUIRE_VALID (self
);
860 static const char *keywords
[] = { "name", nullptr };
861 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "s", keywords
, &name
))
864 self
->inferior
->environment
.unset (name
);
868 /* Getter for "arguments". */
871 infpy_get_args (PyObject
*self
, void *closure
)
873 inferior_object
*inf
= (inferior_object
*) self
;
875 INFPY_REQUIRE_VALID (inf
);
877 const std::string
&args
= inf
->inferior
->args ();
881 return host_string_to_python_string (args
.c_str ()).release ();
884 /* Setter for "arguments". */
887 infpy_set_args (PyObject
*self
, PyObject
*value
, void *closure
)
889 inferior_object
*inf
= (inferior_object
*) self
;
893 PyErr_SetString (PyExc_RuntimeError
, _("Inferior no longer exists."));
897 if (value
== nullptr)
899 PyErr_SetString (PyExc_TypeError
,
900 _("Cannot delete 'arguments' attribute."));
904 if (gdbpy_is_string (value
))
906 gdb::unique_xmalloc_ptr
<char> str
= python_string_to_host_string (value
);
909 inf
->inferior
->set_args (std::string (str
.get ()));
911 else if (PySequence_Check (value
))
913 std::vector
<gdb::unique_xmalloc_ptr
<char>> args
;
914 Py_ssize_t len
= PySequence_Size (value
);
917 for (Py_ssize_t i
= 0; i
< len
; ++i
)
919 gdbpy_ref
<> item (PySequence_ITEM (value
, i
));
922 gdb::unique_xmalloc_ptr
<char> str
923 = python_string_to_host_string (item
.get ());
926 args
.push_back (std::move (str
));
928 std::vector
<char *> argvec
;
929 for (const auto &arg
: args
)
930 argvec
.push_back (arg
.get ());
931 gdb::array_view
<char * const> view (argvec
.data (), argvec
.size ());
932 inf
->inferior
->set_args (view
);
936 PyErr_SetString (PyExc_TypeError
,
937 _("string or sequence required for 'arguments'"));
943 /* Getter for "main_name". */
946 infpy_get_main_name (PyObject
*self
, void *closure
)
948 inferior_object
*inf
= (inferior_object
*) self
;
950 INFPY_REQUIRE_VALID (inf
);
952 const char *name
= nullptr;
955 /* This is unfortunate but the implementation of main_name can
956 reach into memory. It's probably not too important to avoid
957 invalidating the frame cache here, but this scoped-restore is
958 still used, just to keep the code similar to other code in
960 scoped_restore_current_inferior_for_memory restore_inferior
965 catch (const gdb_exception
&except
)
967 /* We can just ignore this. */
973 return host_string_to_python_string (name
).release ();
977 infpy_dealloc (PyObject
*obj
)
979 inferior_object
*inf_obj
= (inferior_object
*) obj
;
981 /* The inferior itself holds a reference to this Python object, which
982 will keep the reference count of this object above zero until GDB
983 deletes the inferior and py_free_inferior is called.
985 Once py_free_inferior has been called then the link between this
986 Python object and the inferior is set to nullptr, and then the
987 reference count on this Python object is decremented.
989 The result of all this is that the link between this Python object and
990 the inferior should always have been set to nullptr before this
991 function is called. */
992 gdb_assert (inf_obj
->inferior
== nullptr);
994 Py_XDECREF (inf_obj
->dict
);
996 Py_TYPE (obj
)->tp_free (obj
);
999 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
1000 Returns the current inferior object. */
1003 gdbpy_selected_inferior (PyObject
*self
, PyObject
*args
)
1005 return ((PyObject
*)
1006 inferior_to_inferior_object (current_inferior ()).release ());
1009 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
1010 gdbpy_initialize_inferior (void)
1012 if (PyType_Ready (&inferior_object_type
) < 0)
1015 if (gdb_pymodule_addobject (gdb_module
, "Inferior",
1016 (PyObject
*) &inferior_object_type
) < 0)
1019 gdb::observers::new_thread
.attach (add_thread_object
, "py-inferior");
1020 gdb::observers::thread_exit
.attach (delete_thread_object
, "py-inferior");
1021 gdb::observers::normal_stop
.attach (python_on_normal_stop
, "py-inferior");
1022 gdb::observers::target_resumed
.attach (python_on_resume
, "py-inferior");
1023 gdb::observers::inferior_call_pre
.attach (python_on_inferior_call_pre
,
1025 gdb::observers::inferior_call_post
.attach (python_on_inferior_call_post
,
1027 gdb::observers::memory_changed
.attach (python_on_memory_change
,
1029 gdb::observers::register_changed
.attach (python_on_register_change
,
1031 gdb::observers::inferior_exit
.attach (python_inferior_exit
, "py-inferior");
1032 /* Need to run after auto-load's new_objfile observer, so that
1033 auto-loaded pretty-printers are available. */
1034 gdb::observers::new_objfile
.attach
1035 (python_new_objfile
, "py-inferior",
1036 { &auto_load_new_objfile_observer_token
});
1037 gdb::observers::all_objfiles_removed
.attach (python_all_objfiles_removed
,
1039 gdb::observers::free_objfile
.attach (python_free_objfile
, "py-inferior");
1040 gdb::observers::inferior_added
.attach (python_new_inferior
, "py-inferior");
1041 gdb::observers::inferior_removed
.attach (python_inferior_deleted
,
1047 GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior
);
1051 static gdb_PyGetSetDef inferior_object_getset
[] =
1053 { "__dict__", gdb_py_generic_dict
, nullptr,
1054 "The __dict__ for this inferior.", &inferior_object_type
},
1055 { "arguments", infpy_get_args
, infpy_set_args
,
1056 "Arguments to this program.", nullptr },
1057 { "num", infpy_get_num
, NULL
, "ID of inferior, as assigned by GDB.", NULL
},
1058 { "connection", infpy_get_connection
, NULL
,
1059 "The gdb.TargetConnection for this inferior.", NULL
},
1060 { "connection_num", infpy_get_connection_num
, NULL
,
1061 "ID of inferior's connection, as assigned by GDB.", NULL
},
1062 { "pid", infpy_get_pid
, NULL
, "PID of inferior, as assigned by the OS.",
1064 { "was_attached", infpy_get_was_attached
, NULL
,
1065 "True if the inferior was created using 'attach'.", NULL
},
1066 { "progspace", infpy_get_progspace
, NULL
, "Program space of this inferior" },
1067 { "main_name", infpy_get_main_name
, nullptr,
1068 "Name of 'main' function, if known.", nullptr },
1072 static PyMethodDef inferior_object_methods
[] =
1074 { "is_valid", infpy_is_valid
, METH_NOARGS
,
1075 "is_valid () -> Boolean.\n\
1076 Return true if this inferior is valid, false if not." },
1077 { "threads", infpy_threads
, METH_NOARGS
,
1078 "Return all the threads of this inferior." },
1079 { "read_memory", (PyCFunction
) infpy_read_memory
,
1080 METH_VARARGS
| METH_KEYWORDS
,
1081 "read_memory (address, length) -> buffer\n\
1082 Return a buffer object for reading from the inferior's memory." },
1083 { "write_memory", (PyCFunction
) infpy_write_memory
,
1084 METH_VARARGS
| METH_KEYWORDS
,
1085 "write_memory (address, buffer [, length])\n\
1086 Write the given buffer object to the inferior's memory." },
1087 { "search_memory", (PyCFunction
) infpy_search_memory
,
1088 METH_VARARGS
| METH_KEYWORDS
,
1089 "search_memory (address, length, pattern) -> long\n\
1090 Return a long with the address of a match, or None." },
1091 /* thread_from_thread_handle is deprecated. */
1092 { "thread_from_thread_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
1093 METH_VARARGS
| METH_KEYWORDS
,
1094 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
1095 Return thread object corresponding to thread handle.\n\
1096 This method is deprecated - use thread_from_handle instead." },
1097 { "thread_from_handle", (PyCFunction
) infpy_thread_from_thread_handle
,
1098 METH_VARARGS
| METH_KEYWORDS
,
1099 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
1100 Return thread object corresponding to thread handle." },
1101 { "architecture", (PyCFunction
) infpy_architecture
, METH_NOARGS
,
1102 "architecture () -> gdb.Architecture\n\
1103 Return architecture of this inferior." },
1104 { "clear_env", (PyCFunction
) infpy_clear_env
, METH_NOARGS
,
1105 "clear_env () -> None\n\
1106 Clear environment of this inferior." },
1107 { "set_env", (PyCFunction
) infpy_set_env
, METH_VARARGS
| METH_KEYWORDS
,
1108 "set_env (name, value) -> None\n\
1109 Set an environment variable of this inferior." },
1110 { "unset_env", (PyCFunction
) infpy_unset_env
, METH_VARARGS
| METH_KEYWORDS
,
1111 "unset_env (name) -> None\n\
1112 Unset an environment of this inferior." },
1116 PyTypeObject inferior_object_type
=
1118 PyVarObject_HEAD_INIT (NULL
, 0)
1119 "gdb.Inferior", /* tp_name */
1120 sizeof (inferior_object
), /* tp_basicsize */
1121 0, /* tp_itemsize */
1122 infpy_dealloc
, /* tp_dealloc */
1127 infpy_repr
, /* tp_repr */
1128 0, /* tp_as_number */
1129 0, /* tp_as_sequence */
1130 0, /* tp_as_mapping */
1134 0, /* tp_getattro */
1135 0, /* tp_setattro */
1136 0, /* tp_as_buffer */
1137 Py_TPFLAGS_DEFAULT
, /* tp_flags */
1138 "GDB inferior object", /* tp_doc */
1139 0, /* tp_traverse */
1141 0, /* tp_richcompare */
1142 0, /* tp_weaklistoffset */
1144 0, /* tp_iternext */
1145 inferior_object_methods
, /* tp_methods */
1147 inferior_object_getset
, /* tp_getset */
1150 0, /* tp_descr_get */
1151 0, /* tp_descr_set */
1152 offsetof (inferior_object
, dict
), /* tp_dictoffset */