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