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