30#include "gdbsupport/gdb_signals.h"
34#include <unordered_map>
37 = std::unordered_map<thread_info *, gdbpy_ref<thread_object>>;
65 inf_obj->inferior = NULL;
67 delete inf_obj->threads;
75#define INFPY_REQUIRE_VALID(Inferior) \
77 if (!Inferior->inferior) \
79 PyErr_SetString (PyExc_RuntimeError, \
80 _("Inferior no longer exists.")); \
88 enum gdb_signal stop_signal;
169 const LONGEST *exit_code = NULL;
176 if (
inf->has_exit_code)
177 exit_code = &
inf->exit_code;
251 gdb_assert (inf_obj !=
nullptr);
318 auto thread_it = inf_obj->threads->find (thr);
319 if (thread_it != inf_obj->threads->end ())
321 ((
PyObject *) (thread_it->second.get ()));
323 PyErr_SetString (PyExc_SystemError,
324 _(
"could not find gdb thread object"));
339 if (thread_obj == NULL)
347 auto ins_result = inf_obj->
threads->emplace
348 (thread_map_t::value_type (tp, std::move (thread_obj)));
350 if (!ins_result.second)
357 (&new_thread_event_object_type,
358 (
PyObject *) ins_result.first->second.get ());
367 gdb::optional<ULONGEST> ,
382 auto it = inf_obj->threads->find (tp);
383 if (it != inf_obj->threads->end ())
389 it->second->thread =
nullptr;
390 inf_obj->threads->erase (it);
407 catch (
const gdb_exception &except)
412 tuple = PyTuple_New (inf_obj->
threads->size ());
416 for (
const thread_map_t::value_type &entry : *inf_obj->
threads)
420 PyTuple_SET_ITEM (tuple, i, thr);
462 if (target ==
nullptr)
484 if (
inf->inferior->attach_flag)
499 gdb_assert (pspace !=
nullptr);
524 return PyList_AsTuple (list.get ());
537 CORE_ADDR addr, length;
538 gdb::unique_xmalloc_ptr<gdb_byte> buffer;
540 static const char *keywords[] = {
"address",
"length", NULL };
545 &addr_obj, &length_obj))
559 buffer.reset ((gdb_byte *)
xmalloc (length));
563 catch (
const gdb_exception &except)
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 };
593 &addr_obj, &pybuf, &length_obj))
597 buffer = (
const gdb_byte *) pybuf.buf;
619 catch (gdb_exception &ex)
621 except = std::move (ex);
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;
654 &start_addr_obj, &length_obj,
659 buffer = (
const gdb_byte *) pybuf.buf;
660 pattern_size = pybuf.len;
670 PyErr_SetString (PyExc_ValueError,
671 _(
"Search range is empty."));
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."));
693 buffer, pattern_size,
696 catch (gdb_exception &ex)
698 except = std::move (ex);
731 static const char *keywords[] = {
"handle", NULL };
738 const gdb_byte *bytes;
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;
758 PyErr_SetString (PyExc_TypeError,
759 _(
"Argument 'handle' must be a thread handle object."));
769 (gdb::array_view<const gdb_byte> (bytes, bytes_len),
774 catch (
const gdb_exception &except)
803 return PyUnicode_FromString (
"<gdb.Inferior (invalid)>");
805 return PyUnicode_FromFormat (
"<gdb.Inferior num=%d, pid=%d>",
830 const char *
name, *val;
831 static const char *keywords[] = {
"name",
"value",
nullptr };
850 static const char *keywords[] = {
"name",
nullptr };
867 const std::string &args =
inf->inferior->args ();
883 PyErr_SetString (PyExc_RuntimeError, _(
"Inferior no longer exists."));
887 if (
value ==
nullptr)
889 PyErr_SetString (PyExc_TypeError,
890 _(
"Cannot delete 'arguments' attribute."));
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)
912 gdb::unique_xmalloc_ptr<char> str
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'"));
942 const char *
name =
nullptr;
955 catch (
const gdb_exception &except)
982 gdb_assert (inf_obj->
inferior ==
nullptr);
984 Py_TYPE (obj)->tp_free (obj);
1042 "Arguments to this program.",
nullptr },
1043 {
"num",
infpy_get_num, NULL,
"ID of inferior, as assigned by GDB.", NULL },
1045 "The gdb.TargetConnection for this inferior.", 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.",
1051 "True if the inferior was created using 'attach'.", NULL },
1054 "Name of 'main' function, if known.",
nullptr },
1061 "is_valid () -> Boolean.\n\
1062Return true if this inferior is valid, false if not." },
1064 "Return all the threads of this inferior." },
1066 METH_VARARGS | METH_KEYWORDS,
1067 "read_memory (address, length) -> buffer\n\
1068Return a buffer object for reading from the inferior's memory." },
1070 METH_VARARGS | METH_KEYWORDS,
1071 "write_memory (address, buffer [, length])\n\
1072Write the given buffer object to the inferior's memory." },
1074 METH_VARARGS | METH_KEYWORDS,
1075 "search_memory (address, length, pattern) -> long\n\
1076Return a long with the address of a match, or None." },
1079 METH_VARARGS | METH_KEYWORDS,
1080 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
1081Return thread object corresponding to thread handle.\n\
1082This method is deprecated - use thread_from_handle instead." },
1084 METH_VARARGS | METH_KEYWORDS,
1085 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
1086Return thread object corresponding to thread handle." },
1088 "architecture () -> gdb.Architecture\n\
1089Return architecture of this inferior." },
1091 "clear_env () -> None\n\
1092Clear environment of this inferior." },
1093 {
"set_env", (PyCFunction)
infpy_set_env, METH_VARARGS | METH_KEYWORDS,
1094 "set_env (name, value) -> None\n\
1095Set an environment variable of this inferior." },
1096 {
"unset_env", (PyCFunction)
infpy_unset_env, METH_VARARGS | METH_KEYWORDS,
1097 "unset_env (name) -> None\n\
1098Unset an environment of this inferior." },
1104 PyVarObject_HEAD_INIT (NULL, 0)
1124 "GDB inferior object",
struct gdbarch * target_gdbarch(void)
gdb::observers::token auto_load_new_objfile_observer_token
void set(unsigned key, void *datum)
gdb_signal stop_signal() const
void read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
void write_memory_with_notification(CORE_ADDR memaddr, const bfd_byte *myaddr, ssize_t len)
void update_thread_list(void)
struct thread_info * inferior_thread(void)
struct thread_info * find_thread_by_handle(gdb::array_view< const gdb_byte > handle, struct inferior *inf)
struct inferior * current_inferior(void)
all_inferiors_range all_inferiors(process_stratum_target *proc_target=nullptr)
observable< ptid_t, CORE_ADDR > inferior_call_pre
observable< struct inferior *, CORE_ADDR, ssize_t, const bfd_byte * > memory_changed
observable< struct inferior * > inferior_added
observable< struct inferior * > inferior_exit
observable< struct objfile * > free_objfile
observable< struct objfile * > new_objfile
observable< struct thread_info * > new_thread
observable< struct inferior * > inferior_removed
observable< ptid_t, CORE_ADDR > inferior_call_post
observable< ptid_t > target_resumed
observable< program_space * > all_objfiles_removed
observable< struct bpstat *, int > normal_stop
observable< frame_info_ptr, int > register_changed
observable< thread_info *, gdb::optional< ULONGEST >, bool > thread_exit
PyObject * gdbarch_to_arch_object(struct gdbarch *gdbarch)
gdbpy_ref target_to_connection_object(process_stratum_target *target)
int emit_continue_event(ptid_t ptid)
gdbpy_ref create_event_object(PyTypeObject *py_type)
int evpy_add_attribute(PyObject *event, const char *name, PyObject *attr)
int evpy_emit_event(PyObject *event, eventregistry_object *registry)
gdbpy_ref create_thread_event_object(PyTypeObject *py_type, PyObject *thread)
int emit_inferior_call_event(inferior_call_kind kind, ptid_t thread, CORE_ADDR addr)
int emit_clear_objfiles_event(program_space *pspace)
int emit_memory_changed_event(CORE_ADDR addr, ssize_t len)
int emit_register_changed_event(frame_info_ptr frame, int regnum)
int emit_new_objfile_event(struct objfile *objfile)
int emit_exited_event(const LONGEST *exit_code, struct inferior *inf)
int emit_free_objfile_event(struct objfile *objfile)
int emit_thread_exit_event(thread_info *thread)
events_object gdb_py_events
bool evregpy_no_listeners_p(eventregistry_object *registry)
static PyMethodDef inferior_object_methods[]
static void delete_thread_object(thread_info *tp, gdb::optional< ULONGEST >, bool)
static PyObject * infpy_get_was_attached(PyObject *self, void *closure)
static void python_on_inferior_call_post(ptid_t thread, CORE_ADDR address)
static void python_all_objfiles_removed(program_space *pspace)
static void python_on_register_change(frame_info_ptr frame, int regnum)
static void python_on_inferior_call_pre(ptid_t thread, CORE_ADDR address)
static int infpy_set_args(PyObject *self, PyObject *value, void *closure)
static PyObject * infpy_search_memory(PyObject *self, PyObject *args, PyObject *kw)
static PyObject * infpy_get_num(PyObject *self, void *closure)
static void infpy_dealloc(PyObject *obj)
static PyObject * infpy_clear_env(PyObject *obj)
static const registry< inferior >::key< inferior_object, infpy_deleter > infpy_inf_data_key
static PyObject * infpy_get_progspace(PyObject *self, void *closure)
gdbpy_ref< inferior_object > inferior_to_inferior_object(struct inferior *inferior)
PyObject * gdbpy_selected_inferior(PyObject *self, PyObject *args)
static PyObject * infpy_get_pid(PyObject *self, void *closure)
static PyObject * infpy_get_main_name(PyObject *self, void *closure)
static PyObject * infpy_read_memory(PyObject *self, PyObject *args, PyObject *kw)
static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION gdbpy_initialize_inferior(void)
static PyObject * infpy_get_args(PyObject *self, void *closure)
static void python_inferior_deleted(struct inferior *inf)
static gdb_PyGetSetDef inferior_object_getset[]
static void python_on_resume(ptid_t ptid)
static PyObject * infpy_write_memory(PyObject *self, PyObject *args, PyObject *kw)
static void python_new_inferior(struct inferior *inf)
static void python_on_memory_change(struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
gdbpy_ref thread_to_thread_object(thread_info *thr)
static void python_on_normal_stop(struct bpstat *bs, int print_frame)
static PyObject * infpy_threads(PyObject *self, PyObject *args)
static PyObject * infpy_unset_env(PyObject *obj, PyObject *args, PyObject *kw)
static PyObject * infpy_set_env(PyObject *obj, PyObject *args, PyObject *kw)
PyObject * gdbpy_inferiors(PyObject *unused, PyObject *unused2)
static void add_thread_object(struct thread_info *tp)
#define INFPY_REQUIRE_VALID(Inferior)
static PyObject * infpy_is_valid(PyObject *self, PyObject *args)
std::unordered_map< thread_info *, gdbpy_ref< thread_object > > thread_map_t
static PyObject * infpy_repr(PyObject *obj)
static void python_free_objfile(struct objfile *objfile)
static PyObject * infpy_get_connection_num(PyObject *self, void *closure)
static PyObject * infpy_get_connection(PyObject *self, void *closure)
PyTypeObject inferior_object_type
static PyObject * infpy_thread_from_thread_handle(PyObject *self, PyObject *args, PyObject *kw)
static void python_inferior_exit(struct inferior *inf)
static void python_new_objfile(struct objfile *objfile)
static PyObject * infpy_architecture(PyObject *self, PyObject *args)
gdbpy_ref< thread_object > create_thread_object(struct thread_info *tp)
PyObject * gdbpy_buffer_to_membuf(gdb::unique_xmalloc_ptr< gdb_byte > buffer, CORE_ADDR address, ULONGEST length)
gdbpy_ref pspace_to_pspace_object(struct program_space *pspace)
gdb::ref_ptr< T, gdbpy_ref_policy< T > > gdbpy_ref
int emit_stop_event(struct bpstat *bs, enum gdb_signal stop_signal)
gdbpy_ref host_string_to_python_string(const char *str)
gdbpy_ref gdb_py_object_from_longest(LONGEST l)
int get_addr_from_python(PyObject *obj, CORE_ADDR *addr)
int gdb_pymodule_addobject(PyObject *module, const char *name, PyObject *object)
gdb::unique_xmalloc_ptr< char > python_string_to_host_string(PyObject *obj)
int gdbpy_is_string(PyObject *obj)
gdbpy_ref gdb_py_object_from_ulongest(ULONGEST l)
int gdbpy_is_value_object(PyObject *obj)
struct value * value_object_to_value(PyObject *self)
void gdbpy_print_stack(void)
std::unique_ptr< Py_buffer, Py_buffer_deleter > Py_buffer_up
int gdb_python_initialized
#define CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF(ARG)
#define CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
#define GDBPY_INITIALIZE_FILE(INIT,...)
#define GDB_PY_HANDLE_EXCEPTION(Exception)
static int gdb_PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, const char **keywords,...)
static void print_frame(const frame_print_options &opts, frame_info_ptr frame, int print_level, enum print_what print_what, int print_args, struct symtab_and_line sal)
PyObject_HEAD struct inferior * inferior
void operator()(inferior_object *obj)
struct gdbarch * arch() const
gdb::array_view< const gdb_byte > contents_all()
struct type * type() const
int target_search_memory(CORE_ADDR start_addr, ULONGEST search_space_len, const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp)