]> Git Repo - binutils.git/blob - gdb/python/py-inferior.c
gdb: remove TYPE_LENGTH
[binutils.git] / gdb / python / py-inferior.c
1 /* Python interface to inferiors.
2
3    Copyright (C) 2009-2022 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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/>.  */
19
20 #include "defs.h"
21 #include "auto-load.h"
22 #include "gdbcore.h"
23 #include "gdbthread.h"
24 #include "inferior.h"
25 #include "objfiles.h"
26 #include "observable.h"
27 #include "python-internal.h"
28 #include "arch-utils.h"
29 #include "language.h"
30 #include "gdbsupport/gdb_signals.h"
31 #include "py-event.h"
32 #include "py-stopevent.h"
33
34 struct threadlist_entry
35 {
36   threadlist_entry (gdbpy_ref<thread_object> &&ref)
37     : thread_obj (std::move (ref))
38   {
39   }
40
41   gdbpy_ref<thread_object> thread_obj;
42   struct threadlist_entry *next;
43 };
44
45 struct inferior_object
46 {
47   PyObject_HEAD
48
49   /* The inferior we represent.  */
50   struct inferior *inferior;
51
52   /* thread_object instances under this inferior.  This list owns a
53      reference to each object it contains.  */
54   struct threadlist_entry *threads;
55
56   /* Number of threads in the list.  */
57   int nthreads;
58 };
59
60 extern PyTypeObject inferior_object_type
61     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
62
63 /* Deleter to clean up when an inferior is removed.  */
64 struct infpy_deleter
65 {
66   void operator() (inferior_object *obj)
67   {
68     struct threadlist_entry *th_entry, *th_tmp;
69
70     if (!gdb_python_initialized)
71       return;
72
73     gdbpy_enter enter_py;
74     gdbpy_ref<inferior_object> inf_obj (obj);
75
76     inf_obj->inferior = NULL;
77
78     /* Deallocate threads list.  */
79     for (th_entry = inf_obj->threads; th_entry != NULL;)
80       {
81         th_tmp = th_entry;
82         th_entry = th_entry->next;
83         delete th_tmp;
84       }
85
86     inf_obj->nthreads = 0;
87   }
88 };
89
90 static const registry<inferior>::key<inferior_object, infpy_deleter>
91      infpy_inf_data_key;
92
93 /* Require that INFERIOR be a valid inferior ID.  */
94 #define INFPY_REQUIRE_VALID(Inferior)                           \
95   do {                                                          \
96     if (!Inferior->inferior)                                    \
97       {                                                         \
98         PyErr_SetString (PyExc_RuntimeError,                    \
99                          _("Inferior no longer exists."));      \
100         return NULL;                                            \
101       }                                                         \
102   } while (0)
103
104 static void
105 python_on_normal_stop (struct bpstat *bs, int print_frame)
106 {
107   enum gdb_signal stop_signal;
108
109   if (!gdb_python_initialized)
110     return;
111
112   if (inferior_ptid == null_ptid)
113     return;
114
115   stop_signal = inferior_thread ()->stop_signal ();
116
117   gdbpy_enter enter_py;
118
119   if (emit_stop_event (bs, stop_signal) < 0)
120     gdbpy_print_stack ();
121 }
122
123 static void
124 python_on_resume (ptid_t ptid)
125 {
126   if (!gdb_python_initialized)
127     return;
128
129   gdbpy_enter enter_py (target_gdbarch ());
130
131   if (emit_continue_event (ptid) < 0)
132     gdbpy_print_stack ();
133 }
134
135 /* Callback, registered as an observer, that notifies Python listeners
136    when an inferior function call is about to be made. */
137
138 static void
139 python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
140 {
141   gdbpy_enter enter_py (target_gdbarch ());
142
143   if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
144     gdbpy_print_stack ();
145 }
146
147 /* Callback, registered as an observer, that notifies Python listeners
148    when an inferior function call has completed. */
149
150 static void
151 python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
152 {
153   gdbpy_enter enter_py (target_gdbarch ());
154
155   if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
156     gdbpy_print_stack ();
157 }
158
159 /* Callback, registered as an observer, that notifies Python listeners
160    when a part of memory has been modified by user action (eg via a
161    'set' command). */
162
163 static void
164 python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
165 {
166   gdbpy_enter enter_py (target_gdbarch ());
167
168   if (emit_memory_changed_event (addr, len) < 0)
169     gdbpy_print_stack ();
170 }
171
172 /* Callback, registered as an observer, that notifies Python listeners
173    when a register has been modified by user action (eg via a 'set'
174    command). */
175
176 static void
177 python_on_register_change (struct frame_info *frame, int regnum)
178 {
179   gdbpy_enter enter_py (target_gdbarch ());
180
181   if (emit_register_changed_event (frame, regnum) < 0)
182     gdbpy_print_stack ();
183 }
184
185 static void
186 python_inferior_exit (struct inferior *inf)
187 {
188   const LONGEST *exit_code = NULL;
189
190   if (!gdb_python_initialized)
191     return;
192
193   gdbpy_enter enter_py (target_gdbarch ());
194
195   if (inf->has_exit_code)
196     exit_code = &inf->exit_code;
197
198   if (emit_exited_event (exit_code, inf) < 0)
199     gdbpy_print_stack ();
200 }
201
202 /* Callback used to notify Python listeners about new objfiles loaded in the
203    inferior.  OBJFILE may be NULL which means that the objfile list has been
204    cleared (emptied).  */
205
206 static void
207 python_new_objfile (struct objfile *objfile)
208 {
209   if (!gdb_python_initialized)
210     return;
211
212   gdbpy_enter enter_py (objfile != NULL
213                         ? objfile->arch ()
214                         : target_gdbarch ());
215
216   if (objfile == NULL)
217     {
218       if (emit_clear_objfiles_event () < 0)
219         gdbpy_print_stack ();
220     }
221   else
222     {
223       if (emit_new_objfile_event (objfile) < 0)
224         gdbpy_print_stack ();
225     }
226 }
227
228 /* Emit a Python event when an objfile is about to be removed.  */
229
230 static void
231 python_free_objfile (struct objfile *objfile)
232 {
233   if (!gdb_python_initialized)
234     return;
235
236   gdbpy_enter enter_py (objfile->arch ());
237
238   if (emit_free_objfile_event (objfile) < 0)
239     gdbpy_print_stack ();
240 }
241
242 /* Return a reference to the Python object of type Inferior
243    representing INFERIOR.  If the object has already been created,
244    return it and increment the reference count,  otherwise, create it.
245    Return NULL on failure.  */
246
247 gdbpy_ref<inferior_object>
248 inferior_to_inferior_object (struct inferior *inferior)
249 {
250   inferior_object *inf_obj;
251
252   inf_obj = infpy_inf_data_key.get (inferior);
253   if (!inf_obj)
254     {
255       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
256       if (!inf_obj)
257         return NULL;
258
259       inf_obj->inferior = inferior;
260       inf_obj->threads = NULL;
261       inf_obj->nthreads = 0;
262
263       /* PyObject_New initializes the new object with a refcount of 1.  This
264          counts for the reference we are keeping in the inferior data.  */
265       infpy_inf_data_key.set (inferior, inf_obj);
266     }
267
268   /* We are returning a new reference.  */
269   gdb_assert (inf_obj != nullptr);
270   return gdbpy_ref<inferior_object>::new_reference (inf_obj);
271 }
272
273 /* Called when a new inferior is created.  Notifies any Python event
274    listeners.  */
275 static void
276 python_new_inferior (struct inferior *inf)
277 {
278   if (!gdb_python_initialized)
279     return;
280
281   gdbpy_enter enter_py;
282
283   if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
284     return;
285
286   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
287   if (inf_obj == NULL)
288     {
289       gdbpy_print_stack ();
290       return;
291     }
292
293   gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
294   if (event == NULL
295       || evpy_add_attribute (event.get (), "inferior",
296                              (PyObject *) inf_obj.get ()) < 0
297       || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
298     gdbpy_print_stack ();
299 }
300
301 /* Called when an inferior is removed.  Notifies any Python event
302    listeners.  */
303 static void
304 python_inferior_deleted (struct inferior *inf)
305 {
306   if (!gdb_python_initialized)
307     return;
308
309   gdbpy_enter enter_py;
310
311   if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
312     return;
313
314   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
315   if (inf_obj == NULL)
316     {
317       gdbpy_print_stack ();
318       return;
319     }
320
321   gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
322   if (event == NULL
323       || evpy_add_attribute (event.get (), "inferior",
324                              (PyObject *) inf_obj.get ()) < 0
325       || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
326     gdbpy_print_stack ();
327 }
328
329 gdbpy_ref<>
330 thread_to_thread_object (thread_info *thr)
331 {
332   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
333   if (inf_obj == NULL)
334     return NULL;
335
336   for (threadlist_entry *thread = inf_obj->threads;
337        thread != NULL;
338        thread = thread->next)
339     if (thread->thread_obj->thread == thr)
340       return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj.get ());
341
342   PyErr_SetString (PyExc_SystemError,
343                    _("could not find gdb thread object"));
344   return NULL;
345 }
346
347 static void
348 add_thread_object (struct thread_info *tp)
349 {
350   inferior_object *inf_obj;
351   struct threadlist_entry *entry;
352
353   if (!gdb_python_initialized)
354     return;
355
356   gdbpy_enter enter_py;
357
358   gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
359   if (thread_obj == NULL)
360     {
361       gdbpy_print_stack ();
362       return;
363     }
364
365   inf_obj = (inferior_object *) thread_obj->inf_obj;
366
367   entry = new threadlist_entry (std::move (thread_obj));
368   entry->next = inf_obj->threads;
369
370   inf_obj->threads = entry;
371   inf_obj->nthreads++;
372
373   if (evregpy_no_listeners_p (gdb_py_events.new_thread))
374     return;
375
376   gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type,
377                                                   (PyObject *)
378                                                   entry->thread_obj.get ());
379   if (event == NULL
380       || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
381     gdbpy_print_stack ();
382 }
383
384 static void
385 delete_thread_object (struct thread_info *tp, int ignore)
386 {
387   struct threadlist_entry **entry, *tmp;
388
389   if (!gdb_python_initialized)
390     return;
391
392   gdbpy_enter enter_py;
393
394   gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
395   if (inf_obj == NULL)
396     return;
397
398   /* Find thread entry in its inferior's thread_list.  */
399   for (entry = &inf_obj->threads; *entry != NULL; entry =
400          &(*entry)->next)
401     if ((*entry)->thread_obj->thread == tp)
402       break;
403
404   if (!*entry)
405     return;
406
407   tmp = *entry;
408   tmp->thread_obj->thread = NULL;
409
410   *entry = (*entry)->next;
411   inf_obj->nthreads--;
412
413   delete tmp;
414 }
415
416 static PyObject *
417 infpy_threads (PyObject *self, PyObject *args)
418 {
419   int i;
420   struct threadlist_entry *entry;
421   inferior_object *inf_obj = (inferior_object *) self;
422   PyObject *tuple;
423
424   INFPY_REQUIRE_VALID (inf_obj);
425
426   try
427     {
428       update_thread_list ();
429     }
430   catch (const gdb_exception &except)
431     {
432       GDB_PY_HANDLE_EXCEPTION (except);
433     }
434
435   tuple = PyTuple_New (inf_obj->nthreads);
436   if (!tuple)
437     return NULL;
438
439   for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
440        i++, entry = entry->next)
441     {
442       PyObject *thr = (PyObject *) entry->thread_obj.get ();
443       Py_INCREF (thr);
444       PyTuple_SET_ITEM (tuple, i, thr);
445     }
446
447   return tuple;
448 }
449
450 static PyObject *
451 infpy_get_num (PyObject *self, void *closure)
452 {
453   inferior_object *inf = (inferior_object *) self;
454
455   INFPY_REQUIRE_VALID (inf);
456
457   return gdb_py_object_from_longest (inf->inferior->num).release ();
458 }
459
460 /* Return the gdb.TargetConnection object for this inferior, or None if a
461    connection does not exist.  */
462
463 static PyObject *
464 infpy_get_connection (PyObject *self, void *closure)
465 {
466   inferior_object *inf = (inferior_object *) self;
467
468   INFPY_REQUIRE_VALID (inf);
469
470   process_stratum_target *target = inf->inferior->process_target ();
471   return target_to_connection_object (target).release ();
472 }
473
474 /* Return the connection number of the given inferior, or None if a
475    connection does not exist.  */
476
477 static PyObject *
478 infpy_get_connection_num (PyObject *self, void *closure)
479 {
480   inferior_object *inf = (inferior_object *) self;
481
482   INFPY_REQUIRE_VALID (inf);
483
484   process_stratum_target *target = inf->inferior->process_target ();
485   if (target == nullptr)
486     Py_RETURN_NONE;
487
488   return gdb_py_object_from_longest (target->connection_number).release ();
489 }
490
491 static PyObject *
492 infpy_get_pid (PyObject *self, void *closure)
493 {
494   inferior_object *inf = (inferior_object *) self;
495
496   INFPY_REQUIRE_VALID (inf);
497
498   return gdb_py_object_from_longest (inf->inferior->pid).release ();
499 }
500
501 static PyObject *
502 infpy_get_was_attached (PyObject *self, void *closure)
503 {
504   inferior_object *inf = (inferior_object *) self;
505
506   INFPY_REQUIRE_VALID (inf);
507   if (inf->inferior->attach_flag)
508     Py_RETURN_TRUE;
509   Py_RETURN_FALSE;
510 }
511
512 /* Getter of gdb.Inferior.progspace.  */
513
514 static PyObject *
515 infpy_get_progspace (PyObject *self, void *closure)
516 {
517   inferior_object *inf = (inferior_object *) self;
518
519   INFPY_REQUIRE_VALID (inf);
520
521   program_space *pspace = inf->inferior->pspace;
522   gdb_assert (pspace != nullptr);
523
524   return pspace_to_pspace_object (pspace).release ();
525 }
526
527 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
528    Returns a tuple of all inferiors.  */
529 PyObject *
530 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
531 {
532   gdbpy_ref<> list (PyList_New (0));
533   if (list == NULL)
534     return NULL;
535
536   for (inferior *inf : all_inferiors ())
537     {
538       gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
539
540       if (inferior == NULL)
541         continue;
542
543       if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
544         return NULL;
545     }
546
547   return PyList_AsTuple (list.get ());
548 }
549
550 /* Membuf and memory manipulation.  */
551
552 /* Implementation of Inferior.read_memory (address, length).
553    Returns a Python buffer object with LENGTH bytes of the inferior's
554    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
555    with a python exception set.  */
556 static PyObject *
557 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
558 {
559   CORE_ADDR addr, length;
560   gdb::unique_xmalloc_ptr<gdb_byte> buffer;
561   PyObject *addr_obj, *length_obj;
562   static const char *keywords[] = { "address", "length", NULL };
563
564   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
565                                         &addr_obj, &length_obj))
566     return NULL;
567
568   if (get_addr_from_python (addr_obj, &addr) < 0
569       || get_addr_from_python (length_obj, &length) < 0)
570     return NULL;
571
572   try
573     {
574       buffer.reset ((gdb_byte *) xmalloc (length));
575
576       read_memory (addr, buffer.get (), length);
577     }
578   catch (const gdb_exception &except)
579     {
580       GDB_PY_HANDLE_EXCEPTION (except);
581     }
582
583
584   return gdbpy_buffer_to_membuf (std::move (buffer), addr, length);
585 }
586
587 /* Implementation of Inferior.write_memory (address, buffer [, length]).
588    Writes the contents of BUFFER (a Python object supporting the read
589    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
590    bytes from BUFFER, or its entire contents if the argument is not
591    provided.  The function returns nothing.  Returns NULL on error, with
592    a python exception set.  */
593 static PyObject *
594 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
595 {
596   struct gdb_exception except;
597   Py_ssize_t buf_len;
598   const gdb_byte *buffer;
599   CORE_ADDR addr, length;
600   PyObject *addr_obj, *length_obj = NULL;
601   static const char *keywords[] = { "address", "buffer", "length", NULL };
602   Py_buffer pybuf;
603
604   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
605                                         &addr_obj, &pybuf, &length_obj))
606     return NULL;
607
608   Py_buffer_up buffer_up (&pybuf);
609   buffer = (const gdb_byte *) pybuf.buf;
610   buf_len = pybuf.len;
611
612   if (get_addr_from_python (addr_obj, &addr) < 0)
613     return nullptr;
614
615   if (!length_obj)
616     length = buf_len;
617   else if (get_addr_from_python (length_obj, &length) < 0)
618     return nullptr;
619
620   try
621     {
622       write_memory_with_notification (addr, buffer, length);
623     }
624   catch (gdb_exception &ex)
625     {
626       except = std::move (ex);
627     }
628
629   GDB_PY_HANDLE_EXCEPTION (except);
630
631   Py_RETURN_NONE;
632 }
633
634 /* Implementation of
635    gdb.search_memory (address, length, pattern).  ADDRESS is the
636    address to start the search.  LENGTH specifies the scope of the
637    search from ADDRESS.  PATTERN is the pattern to search for (and
638    must be a Python object supporting the buffer protocol).
639    Returns a Python Long object holding the address where the pattern
640    was located, or if the pattern was not found, returns None.  Returns NULL
641    on error, with a python exception set.  */
642 static PyObject *
643 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
644 {
645   struct gdb_exception except;
646   CORE_ADDR start_addr, length;
647   static const char *keywords[] = { "address", "length", "pattern", NULL };
648   PyObject *start_addr_obj, *length_obj;
649   Py_ssize_t pattern_size;
650   const gdb_byte *buffer;
651   CORE_ADDR found_addr;
652   int found = 0;
653   Py_buffer pybuf;
654
655   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
656                                         &start_addr_obj, &length_obj,
657                                         &pybuf))
658     return NULL;
659
660   Py_buffer_up buffer_up (&pybuf);
661   buffer = (const gdb_byte *) pybuf.buf;
662   pattern_size = pybuf.len;
663
664   if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
665     return nullptr;
666
667   if (get_addr_from_python (length_obj, &length) < 0)
668     return nullptr;
669
670   if (!length)
671     {
672       PyErr_SetString (PyExc_ValueError,
673                        _("Search range is empty."));
674       return nullptr;
675     }
676   /* Watch for overflows.  */
677   else if (length > CORE_ADDR_MAX
678            || (start_addr + length - 1) < start_addr)
679     {
680       PyErr_SetString (PyExc_ValueError,
681                        _("The search range is too large."));
682       return nullptr;
683     }
684
685   try
686     {
687       found = target_search_memory (start_addr, length,
688                                     buffer, pattern_size,
689                                     &found_addr);
690     }
691   catch (gdb_exception &ex)
692     {
693       except = std::move (ex);
694     }
695
696   GDB_PY_HANDLE_EXCEPTION (except);
697
698   if (found)
699     return gdb_py_object_from_ulongest (found_addr).release ();
700   else
701     Py_RETURN_NONE;
702 }
703
704 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
705    Returns True if this inferior object still exists in GDB.  */
706
707 static PyObject *
708 infpy_is_valid (PyObject *self, PyObject *args)
709 {
710   inferior_object *inf = (inferior_object *) self;
711
712   if (! inf->inferior)
713     Py_RETURN_FALSE;
714
715   Py_RETURN_TRUE;
716 }
717
718 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
719                         ->  gdb.InferiorThread.  */
720
721 static PyObject *
722 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
723 {
724   PyObject *handle_obj;
725   inferior_object *inf_obj = (inferior_object *) self;
726   static const char *keywords[] = { "handle", NULL };
727
728   INFPY_REQUIRE_VALID (inf_obj);
729
730   if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
731     return NULL;
732
733   const gdb_byte *bytes;
734   size_t bytes_len;
735   Py_buffer_up buffer_up;
736   Py_buffer py_buf;
737
738   if (PyObject_CheckBuffer (handle_obj)
739       && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
740     {
741       buffer_up.reset (&py_buf);
742       bytes = (const gdb_byte *) py_buf.buf;
743       bytes_len = py_buf.len;
744     }
745   else if (gdbpy_is_value_object (handle_obj))
746     {
747       struct value *val = value_object_to_value (handle_obj);
748       bytes = value_contents_all (val).data ();
749       bytes_len = value_type (val)->length ();
750     }
751   else
752     {
753       PyErr_SetString (PyExc_TypeError,
754                        _("Argument 'handle' must be a thread handle object."));
755
756       return NULL;
757     }
758
759   try
760     {
761       struct thread_info *thread_info;
762
763       thread_info = find_thread_by_handle
764         (gdb::array_view<const gdb_byte> (bytes, bytes_len),
765          inf_obj->inferior);
766       if (thread_info != NULL)
767         return thread_to_thread_object (thread_info).release ();
768     }
769   catch (const gdb_exception &except)
770     {
771       GDB_PY_HANDLE_EXCEPTION (except);
772     }
773
774   Py_RETURN_NONE;
775 }
776
777 /* Implementation of gdb.Inferior.architecture.  */
778
779 static PyObject *
780 infpy_architecture (PyObject *self, PyObject *args)
781 {
782   inferior_object *inf = (inferior_object *) self;
783
784   INFPY_REQUIRE_VALID (inf);
785
786   return gdbarch_to_arch_object (inf->inferior->gdbarch);
787 }
788
789 /* Implement repr() for gdb.Inferior.  */
790
791 static PyObject *
792 infpy_repr (PyObject *obj)
793 {
794   inferior_object *self = (inferior_object *) obj;
795   inferior *inf = self->inferior;
796
797   if (inf == nullptr)
798     return PyUnicode_FromString ("<gdb.Inferior (invalid)>");
799
800   return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
801                                inf->num, inf->pid);
802 }
803
804
805 static void
806 infpy_dealloc (PyObject *obj)
807 {
808   inferior_object *inf_obj = (inferior_object *) obj;
809
810   /* The inferior itself holds a reference to this Python object, which
811      will keep the reference count of this object above zero until GDB
812      deletes the inferior and py_free_inferior is called.
813
814      Once py_free_inferior has been called then the link between this
815      Python object and the inferior is set to nullptr, and then the
816      reference count on this Python object is decremented.
817
818      The result of all this is that the link between this Python object and
819      the inferior should always have been set to nullptr before this
820      function is called.  */
821   gdb_assert (inf_obj->inferior == nullptr);
822
823   Py_TYPE (obj)->tp_free (obj);
824 }
825
826 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
827    Returns the current inferior object.  */
828
829 PyObject *
830 gdbpy_selected_inferior (PyObject *self, PyObject *args)
831 {
832   return ((PyObject *)
833           inferior_to_inferior_object (current_inferior ()).release ());
834 }
835
836 int
837 gdbpy_initialize_inferior (void)
838 {
839   if (PyType_Ready (&inferior_object_type) < 0)
840     return -1;
841
842   if (gdb_pymodule_addobject (gdb_module, "Inferior",
843                               (PyObject *) &inferior_object_type) < 0)
844     return -1;
845
846   gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
847   gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
848   gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
849   gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
850   gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
851                                             "py-inferior");
852   gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
853                                              "py-inferior");
854   gdb::observers::memory_changed.attach (python_on_memory_change,
855                                          "py-inferior");
856   gdb::observers::register_changed.attach (python_on_register_change,
857                                            "py-inferior");
858   gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
859   /* Need to run after auto-load's new_objfile observer, so that
860      auto-loaded pretty-printers are available.  */
861   gdb::observers::new_objfile.attach
862     (python_new_objfile, "py-inferior",
863      { &auto_load_new_objfile_observer_token });
864   gdb::observers::free_objfile.attach (python_free_objfile, "py-inferior");
865   gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
866   gdb::observers::inferior_removed.attach (python_inferior_deleted,
867                                            "py-inferior");
868
869   return 0;
870 }
871
872 static gdb_PyGetSetDef inferior_object_getset[] =
873 {
874   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
875   { "connection", infpy_get_connection, NULL,
876     "The gdb.TargetConnection for this inferior.", NULL },
877   { "connection_num", infpy_get_connection_num, NULL,
878     "ID of inferior's connection, as assigned by GDB.", NULL },
879   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
880     NULL },
881   { "was_attached", infpy_get_was_attached, NULL,
882     "True if the inferior was created using 'attach'.", NULL },
883   { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
884   { NULL }
885 };
886
887 static PyMethodDef inferior_object_methods[] =
888 {
889   { "is_valid", infpy_is_valid, METH_NOARGS,
890     "is_valid () -> Boolean.\n\
891 Return true if this inferior is valid, false if not." },
892   { "threads", infpy_threads, METH_NOARGS,
893     "Return all the threads of this inferior." },
894   { "read_memory", (PyCFunction) infpy_read_memory,
895     METH_VARARGS | METH_KEYWORDS,
896     "read_memory (address, length) -> buffer\n\
897 Return a buffer object for reading from the inferior's memory." },
898   { "write_memory", (PyCFunction) infpy_write_memory,
899     METH_VARARGS | METH_KEYWORDS,
900     "write_memory (address, buffer [, length])\n\
901 Write the given buffer object to the inferior's memory." },
902   { "search_memory", (PyCFunction) infpy_search_memory,
903     METH_VARARGS | METH_KEYWORDS,
904     "search_memory (address, length, pattern) -> long\n\
905 Return a long with the address of a match, or None." },
906   /* thread_from_thread_handle is deprecated.  */
907   { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
908     METH_VARARGS | METH_KEYWORDS,
909     "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
910 Return thread object corresponding to thread handle.\n\
911 This method is deprecated - use thread_from_handle instead." },
912   { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
913     METH_VARARGS | METH_KEYWORDS,
914     "thread_from_handle (handle) -> gdb.InferiorThread.\n\
915 Return thread object corresponding to thread handle." },
916   { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
917     "architecture () -> gdb.Architecture\n\
918 Return architecture of this inferior." },
919   { NULL }
920 };
921
922 PyTypeObject inferior_object_type =
923 {
924   PyVarObject_HEAD_INIT (NULL, 0)
925   "gdb.Inferior",                 /* tp_name */
926   sizeof (inferior_object),       /* tp_basicsize */
927   0,                              /* tp_itemsize */
928   infpy_dealloc,                  /* tp_dealloc */
929   0,                              /* tp_print */
930   0,                              /* tp_getattr */
931   0,                              /* tp_setattr */
932   0,                              /* tp_compare */
933   infpy_repr,                     /* tp_repr */
934   0,                              /* tp_as_number */
935   0,                              /* tp_as_sequence */
936   0,                              /* tp_as_mapping */
937   0,                              /* tp_hash  */
938   0,                              /* tp_call */
939   0,                              /* tp_str */
940   0,                              /* tp_getattro */
941   0,                              /* tp_setattro */
942   0,                              /* tp_as_buffer */
943   Py_TPFLAGS_DEFAULT,             /* tp_flags */
944   "GDB inferior object",          /* tp_doc */
945   0,                              /* tp_traverse */
946   0,                              /* tp_clear */
947   0,                              /* tp_richcompare */
948   0,                              /* tp_weaklistoffset */
949   0,                              /* tp_iter */
950   0,                              /* tp_iternext */
951   inferior_object_methods,        /* tp_methods */
952   0,                              /* tp_members */
953   inferior_object_getset,         /* tp_getset */
954   0,                              /* tp_base */
955   0,                              /* tp_dict */
956   0,                              /* tp_descr_get */
957   0,                              /* tp_descr_set */
958   0,                              /* tp_dictoffset */
959   0,                              /* tp_init */
960   0                               /* tp_alloc */
961 };
This page took 0.085004 seconds and 4 git commands to generate.