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