]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/py-inferior.c
gdb: remove TYPE_LENGTH
[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 /* 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 };