]> Git Repo - binutils.git/blob - gdb/python/py-inferior.c
3938dd81419a6c581f3ed05c5797aa114eff4075
[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 bpstats *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 connection number of the given inferior, or None if a
419    connection does not exist.  */
420
421 static PyObject *
422 infpy_get_connection_num (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   if (target == nullptr)
430     Py_RETURN_NONE;
431
432   return gdb_py_object_from_longest (target->connection_number).release ();
433 }
434
435 static PyObject *
436 infpy_get_pid (PyObject *self, void *closure)
437 {
438   inferior_object *inf = (inferior_object *) self;
439
440   INFPY_REQUIRE_VALID (inf);
441
442   return gdb_py_object_from_longest (inf->inferior->pid).release ();
443 }
444
445 static PyObject *
446 infpy_get_was_attached (PyObject *self, void *closure)
447 {
448   inferior_object *inf = (inferior_object *) self;
449
450   INFPY_REQUIRE_VALID (inf);
451   if (inf->inferior->attach_flag)
452     Py_RETURN_TRUE;
453   Py_RETURN_FALSE;
454 }
455
456 /* Getter of gdb.Inferior.progspace.  */
457
458 static PyObject *
459 infpy_get_progspace (PyObject *self, void *closure)
460 {
461   inferior_object *inf = (inferior_object *) self;
462
463   INFPY_REQUIRE_VALID (inf);
464
465   program_space *pspace = inf->inferior->pspace;
466   gdb_assert (pspace != nullptr);
467
468   return pspace_to_pspace_object (pspace).release ();
469 }
470
471 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
472    Returns a tuple of all inferiors.  */
473 PyObject *
474 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
475 {
476   gdbpy_ref<> list (PyList_New (0));
477   if (list == NULL)
478     return NULL;
479
480   for (inferior *inf : all_inferiors ())
481     {
482       gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
483
484       if (inferior == NULL)
485         continue;
486
487       if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
488         return NULL;
489     }
490
491   return PyList_AsTuple (list.get ());
492 }
493
494 /* Membuf and memory manipulation.  */
495
496 /* Implementation of Inferior.read_memory (address, length).
497    Returns a Python buffer object with LENGTH bytes of the inferior's
498    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
499    with a python exception set.  */
500 static PyObject *
501 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
502 {
503   CORE_ADDR addr, length;
504   gdb::unique_xmalloc_ptr<gdb_byte> buffer;
505   PyObject *addr_obj, *length_obj;
506   static const char *keywords[] = { "address", "length", NULL };
507
508   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
509                                         &addr_obj, &length_obj))
510     return NULL;
511
512   if (get_addr_from_python (addr_obj, &addr) < 0
513       || get_addr_from_python (length_obj, &length) < 0)
514     return NULL;
515
516   try
517     {
518       buffer.reset ((gdb_byte *) xmalloc (length));
519
520       read_memory (addr, buffer.get (), length);
521     }
522   catch (const gdb_exception &except)
523     {
524       GDB_PY_HANDLE_EXCEPTION (except);
525     }
526
527
528   return gdbpy_buffer_to_membuf (std::move (buffer), addr, length);
529 }
530
531 /* Implementation of Inferior.write_memory (address, buffer [, length]).
532    Writes the contents of BUFFER (a Python object supporting the read
533    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
534    bytes from BUFFER, or its entire contents if the argument is not
535    provided.  The function returns nothing.  Returns NULL on error, with
536    a python exception set.  */
537 static PyObject *
538 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
539 {
540   struct gdb_exception except;
541   Py_ssize_t buf_len;
542   const gdb_byte *buffer;
543   CORE_ADDR addr, length;
544   PyObject *addr_obj, *length_obj = NULL;
545   static const char *keywords[] = { "address", "buffer", "length", NULL };
546   Py_buffer pybuf;
547
548   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
549                                         &addr_obj, &pybuf, &length_obj))
550     return NULL;
551
552   Py_buffer_up buffer_up (&pybuf);
553   buffer = (const gdb_byte *) pybuf.buf;
554   buf_len = pybuf.len;
555
556   if (get_addr_from_python (addr_obj, &addr) < 0)
557     return nullptr;
558
559   if (!length_obj)
560     length = buf_len;
561   else if (get_addr_from_python (length_obj, &length) < 0)
562     return nullptr;
563
564   try
565     {
566       write_memory_with_notification (addr, buffer, length);
567     }
568   catch (gdb_exception &ex)
569     {
570       except = std::move (ex);
571     }
572
573   GDB_PY_HANDLE_EXCEPTION (except);
574
575   Py_RETURN_NONE;
576 }
577
578 /* Implementation of
579    gdb.search_memory (address, length, pattern).  ADDRESS is the
580    address to start the search.  LENGTH specifies the scope of the
581    search from ADDRESS.  PATTERN is the pattern to search for (and
582    must be a Python object supporting the buffer protocol).
583    Returns a Python Long object holding the address where the pattern
584    was located, or if the pattern was not found, returns None.  Returns NULL
585    on error, with a python exception set.  */
586 static PyObject *
587 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
588 {
589   struct gdb_exception except;
590   CORE_ADDR start_addr, length;
591   static const char *keywords[] = { "address", "length", "pattern", NULL };
592   PyObject *start_addr_obj, *length_obj;
593   Py_ssize_t pattern_size;
594   const gdb_byte *buffer;
595   CORE_ADDR found_addr;
596   int found = 0;
597   Py_buffer pybuf;
598
599   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
600                                         &start_addr_obj, &length_obj,
601                                         &pybuf))
602     return NULL;
603
604   Py_buffer_up buffer_up (&pybuf);
605   buffer = (const gdb_byte *) pybuf.buf;
606   pattern_size = pybuf.len;
607
608   if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
609     return nullptr;
610
611   if (get_addr_from_python (length_obj, &length) < 0)
612     return nullptr;
613
614   if (!length)
615     {
616       PyErr_SetString (PyExc_ValueError,
617                        _("Search range is empty."));
618       return nullptr;
619     }
620   /* Watch for overflows.  */
621   else if (length > CORE_ADDR_MAX
622            || (start_addr + length - 1) < start_addr)
623     {
624       PyErr_SetString (PyExc_ValueError,
625                        _("The search range is too large."));
626       return nullptr;
627     }
628
629   try
630     {
631       found = target_search_memory (start_addr, length,
632                                     buffer, pattern_size,
633                                     &found_addr);
634     }
635   catch (gdb_exception &ex)
636     {
637       except = std::move (ex);
638     }
639
640   GDB_PY_HANDLE_EXCEPTION (except);
641
642   if (found)
643     return gdb_py_object_from_ulongest (found_addr).release ();
644   else
645     Py_RETURN_NONE;
646 }
647
648 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
649    Returns True if this inferior object still exists in GDB.  */
650
651 static PyObject *
652 infpy_is_valid (PyObject *self, PyObject *args)
653 {
654   inferior_object *inf = (inferior_object *) self;
655
656   if (! inf->inferior)
657     Py_RETURN_FALSE;
658
659   Py_RETURN_TRUE;
660 }
661
662 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
663                         ->  gdb.InferiorThread.  */
664
665 static PyObject *
666 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
667 {
668   PyObject *handle_obj;
669   inferior_object *inf_obj = (inferior_object *) self;
670   static const char *keywords[] = { "handle", NULL };
671
672   INFPY_REQUIRE_VALID (inf_obj);
673
674   if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
675     return NULL;
676
677   const gdb_byte *bytes;
678   size_t bytes_len;
679   Py_buffer_up buffer_up;
680   Py_buffer py_buf;
681
682   if (PyObject_CheckBuffer (handle_obj)
683       && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
684     {
685       buffer_up.reset (&py_buf);
686       bytes = (const gdb_byte *) py_buf.buf;
687       bytes_len = py_buf.len;
688     }
689   else if (gdbpy_is_value_object (handle_obj))
690     {
691       struct value *val = value_object_to_value (handle_obj);
692       bytes = value_contents_all (val).data ();
693       bytes_len = TYPE_LENGTH (value_type (val));
694     }
695   else
696     {
697       PyErr_SetString (PyExc_TypeError,
698                        _("Argument 'handle' must be a thread handle object."));
699
700       return NULL;
701     }
702
703   try
704     {
705       struct thread_info *thread_info;
706
707       thread_info = find_thread_by_handle
708         (gdb::array_view<const gdb_byte> (bytes, bytes_len),
709          inf_obj->inferior);
710       if (thread_info != NULL)
711         return thread_to_thread_object (thread_info).release ();
712     }
713   catch (const gdb_exception &except)
714     {
715       GDB_PY_HANDLE_EXCEPTION (except);
716     }
717
718   Py_RETURN_NONE;
719 }
720
721 /* Implementation of gdb.Inferior.architecture.  */
722
723 static PyObject *
724 infpy_architecture (PyObject *self, PyObject *args)
725 {
726   inferior_object *inf = (inferior_object *) self;
727
728   INFPY_REQUIRE_VALID (inf);
729
730   return gdbarch_to_arch_object (inf->inferior->gdbarch);
731 }
732
733 /* Implement repr() for gdb.Inferior.  */
734
735 static PyObject *
736 infpy_repr (PyObject *obj)
737 {
738   inferior_object *self = (inferior_object *) obj;
739   inferior *inf = self->inferior;
740
741   if (inf == nullptr)
742     return PyString_FromString ("<gdb.Inferior (invalid)>");
743
744   return PyString_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
745                               inf->num, inf->pid);
746 }
747
748
749 static void
750 infpy_dealloc (PyObject *obj)
751 {
752   inferior_object *inf_obj = (inferior_object *) obj;
753
754   /* The inferior itself holds a reference to this Python object, which
755      will keep the reference count of this object above zero until GDB
756      deletes the inferior and py_free_inferior is called.
757
758      Once py_free_inferior has been called then the link between this
759      Python object and the inferior is set to nullptr, and then the
760      reference count on this Python object is decremented.
761
762      The result of all this is that the link between this Python object and
763      the inferior should always have been set to nullptr before this
764      function is called.  */
765   gdb_assert (inf_obj->inferior == nullptr);
766
767   Py_TYPE (obj)->tp_free (obj);
768 }
769
770 /* Clear the INFERIOR pointer in an Inferior object and clear the
771    thread list.  */
772 static void
773 py_free_inferior (struct inferior *inf, void *datum)
774 {
775   struct threadlist_entry *th_entry, *th_tmp;
776
777   if (!gdb_python_initialized)
778     return;
779
780   gdbpy_enter enter_py (python_gdbarch, python_language);
781   gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
782
783   inf_obj->inferior = NULL;
784
785   /* Deallocate threads list.  */
786   for (th_entry = inf_obj->threads; th_entry != NULL;)
787     {
788       th_tmp = th_entry;
789       th_entry = th_entry->next;
790       delete th_tmp;
791     }
792
793   inf_obj->nthreads = 0;
794 }
795
796 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
797    Returns the current inferior object.  */
798
799 PyObject *
800 gdbpy_selected_inferior (PyObject *self, PyObject *args)
801 {
802   return ((PyObject *)
803           inferior_to_inferior_object (current_inferior ()).release ());
804 }
805
806 void _initialize_py_inferior ();
807 void
808 _initialize_py_inferior ()
809 {
810   infpy_inf_data_key =
811     register_inferior_data_with_cleanup (NULL, py_free_inferior);
812 }
813
814 int
815 gdbpy_initialize_inferior (void)
816 {
817   if (PyType_Ready (&inferior_object_type) < 0)
818     return -1;
819
820   if (gdb_pymodule_addobject (gdb_module, "Inferior",
821                               (PyObject *) &inferior_object_type) < 0)
822     return -1;
823
824   gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
825   gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
826   gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
827   gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
828   gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
829                                             "py-inferior");
830   gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
831                                              "py-inferior");
832   gdb::observers::memory_changed.attach (python_on_memory_change,
833                                          "py-inferior");
834   gdb::observers::register_changed.attach (python_on_register_change,
835                                            "py-inferior");
836   gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
837   /* Need to run after auto-load's new_objfile observer, so that
838      auto-loaded pretty-printers are available.  */
839   gdb::observers::new_objfile.attach
840     (python_new_objfile, "py-inferior",
841      { &auto_load_new_objfile_observer_token });
842   gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
843   gdb::observers::inferior_removed.attach (python_inferior_deleted,
844                                            "py-inferior");
845
846   return 0;
847 }
848
849 static gdb_PyGetSetDef inferior_object_getset[] =
850 {
851   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
852   { "connection_num", infpy_get_connection_num, NULL,
853     "ID of inferior's connection, as assigned by GDB.", NULL },
854   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
855     NULL },
856   { "was_attached", infpy_get_was_attached, NULL,
857     "True if the inferior was created using 'attach'.", NULL },
858   { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
859   { NULL }
860 };
861
862 static PyMethodDef inferior_object_methods[] =
863 {
864   { "is_valid", infpy_is_valid, METH_NOARGS,
865     "is_valid () -> Boolean.\n\
866 Return true if this inferior is valid, false if not." },
867   { "threads", infpy_threads, METH_NOARGS,
868     "Return all the threads of this inferior." },
869   { "read_memory", (PyCFunction) infpy_read_memory,
870     METH_VARARGS | METH_KEYWORDS,
871     "read_memory (address, length) -> buffer\n\
872 Return a buffer object for reading from the inferior's memory." },
873   { "write_memory", (PyCFunction) infpy_write_memory,
874     METH_VARARGS | METH_KEYWORDS,
875     "write_memory (address, buffer [, length])\n\
876 Write the given buffer object to the inferior's memory." },
877   { "search_memory", (PyCFunction) infpy_search_memory,
878     METH_VARARGS | METH_KEYWORDS,
879     "search_memory (address, length, pattern) -> long\n\
880 Return a long with the address of a match, or None." },
881   /* thread_from_thread_handle is deprecated.  */
882   { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
883     METH_VARARGS | METH_KEYWORDS,
884     "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
885 Return thread object corresponding to thread handle.\n\
886 This method is deprecated - use thread_from_handle instead." },
887   { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
888     METH_VARARGS | METH_KEYWORDS,
889     "thread_from_handle (handle) -> gdb.InferiorThread.\n\
890 Return thread object corresponding to thread handle." },
891   { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
892     "architecture () -> gdb.Architecture\n\
893 Return architecture of this inferior." },
894   { NULL }
895 };
896
897 PyTypeObject inferior_object_type =
898 {
899   PyVarObject_HEAD_INIT (NULL, 0)
900   "gdb.Inferior",                 /* tp_name */
901   sizeof (inferior_object),       /* tp_basicsize */
902   0,                              /* tp_itemsize */
903   infpy_dealloc,                  /* tp_dealloc */
904   0,                              /* tp_print */
905   0,                              /* tp_getattr */
906   0,                              /* tp_setattr */
907   0,                              /* tp_compare */
908   infpy_repr,                     /* tp_repr */
909   0,                              /* tp_as_number */
910   0,                              /* tp_as_sequence */
911   0,                              /* tp_as_mapping */
912   0,                              /* tp_hash  */
913   0,                              /* tp_call */
914   0,                              /* tp_str */
915   0,                              /* tp_getattro */
916   0,                              /* tp_setattro */
917   0,                              /* tp_as_buffer */
918   Py_TPFLAGS_DEFAULT,             /* tp_flags */
919   "GDB inferior object",          /* tp_doc */
920   0,                              /* tp_traverse */
921   0,                              /* tp_clear */
922   0,                              /* tp_richcompare */
923   0,                              /* tp_weaklistoffset */
924   0,                              /* tp_iter */
925   0,                              /* tp_iternext */
926   inferior_object_methods,        /* tp_methods */
927   0,                              /* tp_members */
928   inferior_object_getset,         /* tp_getset */
929   0,                              /* tp_base */
930   0,                              /* tp_dict */
931   0,                              /* tp_descr_get */
932   0,                              /* tp_descr_set */
933   0,                              /* tp_dictoffset */
934   0,                              /* tp_init */
935   0                               /* tp_alloc */
936 };
This page took 0.067474 seconds and 2 git commands to generate.