30#include "gdbsupport/gdb_signals.h"
33#include <unordered_map>
36 = std::unordered_map<thread_info *, gdbpy_ref<thread_object>>;
64 inf_obj->inferior = NULL;
66 delete inf_obj->threads;
74#define INFPY_REQUIRE_VALID(Inferior) \
76 if (!Inferior->inferior) \
78 PyErr_SetString (PyExc_RuntimeError, \
79 _("Inferior no longer exists.")); \
87 enum gdb_signal stop_signal;
168 const LONGEST *exit_code = NULL;
175 if (
inf->has_exit_code)
176 exit_code = &
inf->exit_code;
248 gdb_assert (inf_obj !=
nullptr);
275 (PyObject *) inf_obj.get ()) < 0
303 (PyObject *) inf_obj.get ()) < 0
315 auto thread_it = inf_obj->threads->find (thr);
316 if (thread_it != inf_obj->threads->end ())
318 ((PyObject *) (thread_it->second.get ()));
320 PyErr_SetString (PyExc_SystemError,
321 _(
"could not find gdb thread object"));
336 if (thread_obj == NULL)
344 auto ins_result = inf_obj->
threads->emplace
345 (thread_map_t::value_type (tp, std::move (thread_obj)));
347 if (!ins_result.second)
354 (&new_thread_event_object_type,
355 (PyObject *) ins_result.first->second.get ());
374 auto it = inf_obj->threads->find (tp);
375 if (it != inf_obj->threads->end ())
381 it->second->thread =
nullptr;
382 inf_obj->threads->erase (it);
399 catch (
const gdb_exception &except)
404 tuple = PyTuple_New (inf_obj->
threads->size ());
408 for (
const thread_map_t::value_type &entry : *inf_obj->
threads)
410 PyObject *thr = (PyObject *) entry.second.get ();
412 PyTuple_SET_ITEM (tuple, i, thr);
454 if (target ==
nullptr)
476 if (
inf->inferior->attach_flag)
491 gdb_assert (pspace !=
nullptr);
512 if (PyList_Append (list.get (), (PyObject *)
inferior.get ()) != 0)
516 return PyList_AsTuple (list.get ());
528 CORE_ADDR addr, length;
529 gdb::unique_xmalloc_ptr<gdb_byte> buffer;
530 PyObject *addr_obj, *length_obj;
531 static const char *keywords[] = {
"address",
"length", NULL };
534 &addr_obj, &length_obj))
543 buffer.reset ((gdb_byte *)
xmalloc (length));
547 catch (
const gdb_exception &except)
565 struct gdb_exception except;
567 const gdb_byte *buffer;
568 CORE_ADDR addr, length;
569 PyObject *addr_obj, *length_obj = NULL;
570 static const char *keywords[] = {
"address",
"buffer",
"length", NULL };
574 &addr_obj, &pybuf, &length_obj))
578 buffer = (
const gdb_byte *) pybuf.buf;
593 catch (gdb_exception &ex)
595 except = std::move (ex);
614 struct gdb_exception except;
615 CORE_ADDR start_addr, length;
616 static const char *keywords[] = {
"address",
"length",
"pattern", NULL };
617 PyObject *start_addr_obj, *length_obj;
618 Py_ssize_t pattern_size;
619 const gdb_byte *buffer;
620 CORE_ADDR found_addr;
625 &start_addr_obj, &length_obj,
630 buffer = (
const gdb_byte *) pybuf.buf;
631 pattern_size = pybuf.len;
641 PyErr_SetString (PyExc_ValueError,
642 _(
"Search range is empty."));
646 else if (length > CORE_ADDR_MAX
647 || (start_addr + length - 1) < start_addr)
649 PyErr_SetString (PyExc_ValueError,
650 _(
"The search range is too large."));
657 buffer, pattern_size,
660 catch (gdb_exception &ex)
662 except = std::move (ex);
693 PyObject *handle_obj;
695 static const char *keywords[] = {
"handle", NULL };
702 const gdb_byte *bytes;
707 if (PyObject_CheckBuffer (handle_obj)
708 && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
710 buffer_up.reset (&py_buf);
711 bytes = (
const gdb_byte *) py_buf.buf;
712 bytes_len = py_buf.len;
722 PyErr_SetString (PyExc_TypeError,
723 _(
"Argument 'handle' must be a thread handle object."));
733 (gdb::array_view<const gdb_byte> (bytes, bytes_len),
738 catch (
const gdb_exception &except)
767 return PyUnicode_FromString (
"<gdb.Inferior (invalid)>");
769 return PyUnicode_FromFormat (
"<gdb.Inferior num=%d, pid=%d>",
790 gdb_assert (inf_obj->
inferior ==
nullptr);
792 Py_TYPE (obj)->tp_free (obj);
843 {
"num",
infpy_get_num, NULL,
"ID of inferior, as assigned by GDB.", NULL },
845 "The gdb.TargetConnection for this inferior.", NULL },
847 "ID of inferior's connection, as assigned by GDB.", NULL },
848 {
"pid",
infpy_get_pid, NULL,
"PID of inferior, as assigned by the OS.",
851 "True if the inferior was created using 'attach'.", NULL },
859 "is_valid () -> Boolean.\n\
860Return true if this inferior is valid, false if not." },
862 "Return all the threads of this inferior." },
864 METH_VARARGS | METH_KEYWORDS,
865 "read_memory (address, length) -> buffer\n\
866Return a buffer object for reading from the inferior's memory." },
868 METH_VARARGS | METH_KEYWORDS,
869 "write_memory (address, buffer [, length])\n\
870Write the given buffer object to the inferior's memory." },
872 METH_VARARGS | METH_KEYWORDS,
873 "search_memory (address, length, pattern) -> long\n\
874Return a long with the address of a match, or None." },
877 METH_VARARGS | METH_KEYWORDS,
878 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
879Return thread object corresponding to thread handle.\n\
880This method is deprecated - use thread_from_handle instead." },
882 METH_VARARGS | METH_KEYWORDS,
883 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
884Return thread object corresponding to thread handle." },
886 "architecture () -> gdb.Architecture\n\
887Return architecture of this inferior." },
893 PyVarObject_HEAD_INIT (NULL, 0)
913 "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< struct thread_info *, int > thread_exit
observable< ptid_t, CORE_ADDR > inferior_call_post
observable< ptid_t > target_resumed
observable< struct bpstat *, int > normal_stop
observable< frame_info_ptr, int > register_changed
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)
int emit_clear_objfiles_event(void)
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_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)
events_object gdb_py_events
bool evregpy_no_listeners_p(eventregistry_object *registry)
static PyMethodDef inferior_object_methods[]
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_on_register_change(frame_info_ptr frame, int regnum)
static void python_on_inferior_call_pre(ptid_t thread, CORE_ADDR address)
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 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)
std::unordered_map< thread_info *, gdbpy_ref< thread_object > > thread_map_t
static PyObject * infpy_get_pid(PyObject *self, void *closure)
static void delete_thread_object(struct thread_info *tp, int ignore)
static PyObject * infpy_read_memory(PyObject *self, PyObject *args, PyObject *kw)
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)
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)
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)
int gdbpy_initialize_inferior(void)
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 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)
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 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
int target_search_memory(CORE_ADDR start_addr, ULONGEST search_space_len, const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp)
struct type * value_type(const struct value *value)
gdb::array_view< const gdb_byte > value_contents_all(struct value *value)