Make exception handling more efficient
[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 (const gdb_exception &except)
397 {
398 GDB_PY_HANDLE_EXCEPTION (except);
399 }
400
401 tuple = PyTuple_New (inf_obj->nthreads);
402 if (!tuple)
403 return NULL;
404
405 for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
406 i++, entry = entry->next)
407 {
408 Py_INCREF (entry->thread_obj);
409 PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj);
410 }
411
412 return tuple;
413 }
414
415 static PyObject *
416 infpy_get_num (PyObject *self, void *closure)
417 {
418 inferior_object *inf = (inferior_object *) self;
419
420 INFPY_REQUIRE_VALID (inf);
421
422 return PyLong_FromLong (inf->inferior->num);
423 }
424
425 static PyObject *
426 infpy_get_pid (PyObject *self, void *closure)
427 {
428 inferior_object *inf = (inferior_object *) self;
429
430 INFPY_REQUIRE_VALID (inf);
431
432 return PyLong_FromLong (inf->inferior->pid);
433 }
434
435 static PyObject *
436 infpy_get_was_attached (PyObject *self, void *closure)
437 {
438 inferior_object *inf = (inferior_object *) self;
439
440 INFPY_REQUIRE_VALID (inf);
441 if (inf->inferior->attach_flag)
442 Py_RETURN_TRUE;
443 Py_RETURN_FALSE;
444 }
445
446 /* Getter of gdb.Inferior.progspace. */
447
448 static PyObject *
449 infpy_get_progspace (PyObject *self, void *closure)
450 {
451 inferior_object *inf = (inferior_object *) self;
452
453 INFPY_REQUIRE_VALID (inf);
454
455 program_space *pspace = inf->inferior->pspace;
456 gdb_assert (pspace != nullptr);
457
458 return pspace_to_pspace_object (pspace).release ();
459 }
460
461 static int
462 build_inferior_list (struct inferior *inf, void *arg)
463 {
464 PyObject *list = (PyObject *) arg;
465 gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
466
467 if (inferior == NULL)
468 return 0;
469
470 return PyList_Append (list, (PyObject *) inferior.get ()) ? 1 : 0;
471 }
472
473 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
474 Returns a tuple of all inferiors. */
475 PyObject *
476 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
477 {
478 gdbpy_ref<> list (PyList_New (0));
479 if (list == NULL)
480 return NULL;
481
482 if (iterate_over_inferiors (build_inferior_list, list.get ()))
483 return NULL;
484
485 return PyList_AsTuple (list.get ());
486 }
487
488 /* Membuf and memory manipulation. */
489
490 /* Implementation of Inferior.read_memory (address, length).
491 Returns a Python buffer object with LENGTH bytes of the inferior's
492 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
493 with a python exception set. */
494 static PyObject *
495 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
496 {
497 CORE_ADDR addr, length;
498 gdb::unique_xmalloc_ptr<gdb_byte> buffer;
499 PyObject *addr_obj, *length_obj, *result;
500 static const char *keywords[] = { "address", "length", NULL };
501
502 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
503 &addr_obj, &length_obj))
504 return NULL;
505
506 if (get_addr_from_python (addr_obj, &addr) < 0
507 || get_addr_from_python (length_obj, &length) < 0)
508 return NULL;
509
510 try
511 {
512 buffer.reset ((gdb_byte *) xmalloc (length));
513
514 read_memory (addr, buffer.get (), length);
515 }
516 catch (const gdb_exception &except)
517 {
518 GDB_PY_HANDLE_EXCEPTION (except);
519 }
520
521 gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
522 &membuf_object_type));
523 if (membuf_obj == NULL)
524 return NULL;
525
526 membuf_obj->buffer = buffer.release ();
527 membuf_obj->addr = addr;
528 membuf_obj->length = length;
529
530 #ifdef IS_PY3K
531 result = PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
532 #else
533 result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj.get (), 0,
534 Py_END_OF_BUFFER);
535 #endif
536
537 return result;
538 }
539
540 /* Implementation of Inferior.write_memory (address, buffer [, length]).
541 Writes the contents of BUFFER (a Python object supporting the read
542 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
543 bytes from BUFFER, or its entire contents if the argument is not
544 provided. The function returns nothing. Returns NULL on error, with
545 a python exception set. */
546 static PyObject *
547 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
548 {
549 struct gdb_exception except;
550 Py_ssize_t buf_len;
551 const gdb_byte *buffer;
552 CORE_ADDR addr, length;
553 PyObject *addr_obj, *length_obj = NULL;
554 static const char *keywords[] = { "address", "buffer", "length", NULL };
555 Py_buffer pybuf;
556
557 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
558 &addr_obj, &pybuf, &length_obj))
559 return NULL;
560
561 Py_buffer_up buffer_up (&pybuf);
562 buffer = (const gdb_byte *) pybuf.buf;
563 buf_len = pybuf.len;
564
565 if (get_addr_from_python (addr_obj, &addr) < 0)
566 return nullptr;
567
568 if (!length_obj)
569 length = buf_len;
570 else if (get_addr_from_python (length_obj, &length) < 0)
571 return nullptr;
572
573 try
574 {
575 write_memory_with_notification (addr, buffer, length);
576 }
577 catch (gdb_exception &ex)
578 {
579 except = std::move (ex);
580 }
581
582 GDB_PY_HANDLE_EXCEPTION (except);
583
584 Py_RETURN_NONE;
585 }
586
587 /* Destructor of Membuf objects. */
588 static void
589 mbpy_dealloc (PyObject *self)
590 {
591 xfree (((membuf_object *) self)->buffer);
592 Py_TYPE (self)->tp_free (self);
593 }
594
595 /* Return a description of the Membuf object. */
596 static PyObject *
597 mbpy_str (PyObject *self)
598 {
599 membuf_object *membuf_obj = (membuf_object *) self;
600
601 return PyString_FromFormat (_("Memory buffer for address %s, \
602 which is %s bytes long."),
603 paddress (python_gdbarch, membuf_obj->addr),
604 pulongest (membuf_obj->length));
605 }
606
607 #ifdef IS_PY3K
608
609 static int
610 get_buffer (PyObject *self, Py_buffer *buf, int flags)
611 {
612 membuf_object *membuf_obj = (membuf_object *) self;
613 int ret;
614
615 ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
616 membuf_obj->length, 0,
617 PyBUF_CONTIG);
618
619 /* Despite the documentation saying this field is a "const char *",
620 in Python 3.4 at least, it's really a "char *". */
621 buf->format = (char *) "c";
622
623 return ret;
624 }
625
626 #else
627
628 static Py_ssize_t
629 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
630 {
631 membuf_object *membuf_obj = (membuf_object *) self;
632
633 if (segment)
634 {
635 PyErr_SetString (PyExc_SystemError,
636 _("The memory buffer supports only one segment."));
637 return -1;
638 }
639
640 *ptrptr = membuf_obj->buffer;
641
642 return membuf_obj->length;
643 }
644
645 static Py_ssize_t
646 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
647 {
648 return get_read_buffer (self, segment, ptrptr);
649 }
650
651 static Py_ssize_t
652 get_seg_count (PyObject *self, Py_ssize_t *lenp)
653 {
654 if (lenp)
655 *lenp = ((membuf_object *) self)->length;
656
657 return 1;
658 }
659
660 static Py_ssize_t
661 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
662 {
663 void *ptr = NULL;
664 Py_ssize_t ret;
665
666 ret = get_read_buffer (self, segment, &ptr);
667 *ptrptr = (char *) ptr;
668
669 return ret;
670 }
671
672 #endif /* IS_PY3K */
673
674 /* Implementation of
675 gdb.search_memory (address, length, pattern). ADDRESS is the
676 address to start the search. LENGTH specifies the scope of the
677 search from ADDRESS. PATTERN is the pattern to search for (and
678 must be a Python object supporting the buffer protocol).
679 Returns a Python Long object holding the address where the pattern
680 was located, or if the pattern was not found, returns None. Returns NULL
681 on error, with a python exception set. */
682 static PyObject *
683 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
684 {
685 struct gdb_exception except;
686 CORE_ADDR start_addr, length;
687 static const char *keywords[] = { "address", "length", "pattern", NULL };
688 PyObject *start_addr_obj, *length_obj;
689 Py_ssize_t pattern_size;
690 const gdb_byte *buffer;
691 CORE_ADDR found_addr;
692 int found = 0;
693 Py_buffer pybuf;
694
695 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
696 &start_addr_obj, &length_obj,
697 &pybuf))
698 return NULL;
699
700 Py_buffer_up buffer_up (&pybuf);
701 buffer = (const gdb_byte *) pybuf.buf;
702 pattern_size = pybuf.len;
703
704 if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
705 return nullptr;
706
707 if (get_addr_from_python (length_obj, &length) < 0)
708 return nullptr;
709
710 if (!length)
711 {
712 PyErr_SetString (PyExc_ValueError,
713 _("Search range is empty."));
714 return nullptr;
715 }
716 /* Watch for overflows. */
717 else if (length > CORE_ADDR_MAX
718 || (start_addr + length - 1) < start_addr)
719 {
720 PyErr_SetString (PyExc_ValueError,
721 _("The search range is too large."));
722 return nullptr;
723 }
724
725 try
726 {
727 found = target_search_memory (start_addr, length,
728 buffer, pattern_size,
729 &found_addr);
730 }
731 catch (gdb_exception &ex)
732 {
733 except = std::move (ex);
734 }
735
736 GDB_PY_HANDLE_EXCEPTION (except);
737
738 if (found)
739 return PyLong_FromLong (found_addr);
740 else
741 Py_RETURN_NONE;
742 }
743
744 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
745 Returns True if this inferior object still exists in GDB. */
746
747 static PyObject *
748 infpy_is_valid (PyObject *self, PyObject *args)
749 {
750 inferior_object *inf = (inferior_object *) self;
751
752 if (! inf->inferior)
753 Py_RETURN_FALSE;
754
755 Py_RETURN_TRUE;
756 }
757
758 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
759 -> gdb.InferiorThread. */
760
761 static PyObject *
762 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
763 {
764 PyObject *handle_obj;
765 inferior_object *inf_obj = (inferior_object *) self;
766 static const char *keywords[] = { "handle", NULL };
767
768 INFPY_REQUIRE_VALID (inf_obj);
769
770 if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
771 return NULL;
772
773 const gdb_byte *bytes;
774 size_t bytes_len;
775 Py_buffer_up buffer_up;
776 Py_buffer py_buf;
777
778 if (PyObject_CheckBuffer (handle_obj)
779 && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
780 {
781 buffer_up.reset (&py_buf);
782 bytes = (const gdb_byte *) py_buf.buf;
783 bytes_len = py_buf.len;
784 }
785 else if (gdbpy_is_value_object (handle_obj))
786 {
787 struct value *val = value_object_to_value (handle_obj);
788 bytes = value_contents_all (val);
789 bytes_len = TYPE_LENGTH (value_type (val));
790 }
791 else
792 {
793 PyErr_SetString (PyExc_TypeError,
794 _("Argument 'handle' must be a thread handle object."));
795
796 return NULL;
797 }
798
799 try
800 {
801 struct thread_info *thread_info;
802
803 thread_info = find_thread_by_handle
804 (gdb::array_view<const gdb_byte> (bytes, bytes_len),
805 inf_obj->inferior);
806 if (thread_info != NULL)
807 return thread_to_thread_object (thread_info).release ();
808 }
809 catch (const gdb_exception &except)
810 {
811 GDB_PY_HANDLE_EXCEPTION (except);
812 }
813
814 Py_RETURN_NONE;
815 }
816
817 /* Implementation of gdb.Inferior.architecture. */
818
819 static PyObject *
820 infpy_architecture (PyObject *self, PyObject *args)
821 {
822 inferior_object *inf = (inferior_object *) self;
823
824 INFPY_REQUIRE_VALID (inf);
825
826 return gdbarch_to_arch_object (inf->inferior->gdbarch);
827 }
828
829 /* Implement repr() for gdb.Inferior. */
830
831 static PyObject *
832 infpy_repr (PyObject *obj)
833 {
834 inferior_object *self = (inferior_object *) obj;
835 inferior *inf = self->inferior;
836
837 if (inf == nullptr)
838 return PyString_FromString ("<gdb.Inferior (invalid)>");
839
840 return PyString_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
841 inf->num, inf->pid);
842 }
843
844
845 static void
846 infpy_dealloc (PyObject *obj)
847 {
848 inferior_object *inf_obj = (inferior_object *) obj;
849 struct inferior *inf = inf_obj->inferior;
850
851 if (! inf)
852 return;
853
854 set_inferior_data (inf, infpy_inf_data_key, NULL);
855 }
856
857 /* Clear the INFERIOR pointer in an Inferior object and clear the
858 thread list. */
859 static void
860 py_free_inferior (struct inferior *inf, void *datum)
861 {
862 gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
863 struct threadlist_entry *th_entry, *th_tmp;
864
865 if (!gdb_python_initialized)
866 return;
867
868 gdbpy_enter enter_py (python_gdbarch, python_language);
869
870 inf_obj->inferior = NULL;
871
872 /* Deallocate threads list. */
873 for (th_entry = inf_obj->threads; th_entry != NULL;)
874 {
875 Py_DECREF (th_entry->thread_obj);
876
877 th_tmp = th_entry;
878 th_entry = th_entry->next;
879 xfree (th_tmp);
880 }
881
882 inf_obj->nthreads = 0;
883 }
884
885 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
886 Returns the current inferior object. */
887
888 PyObject *
889 gdbpy_selected_inferior (PyObject *self, PyObject *args)
890 {
891 return ((PyObject *)
892 inferior_to_inferior_object (current_inferior ()).release ());
893 }
894
895 int
896 gdbpy_initialize_inferior (void)
897 {
898 if (PyType_Ready (&inferior_object_type) < 0)
899 return -1;
900
901 if (gdb_pymodule_addobject (gdb_module, "Inferior",
902 (PyObject *) &inferior_object_type) < 0)
903 return -1;
904
905 infpy_inf_data_key =
906 register_inferior_data_with_cleanup (NULL, py_free_inferior);
907
908 gdb::observers::new_thread.attach (add_thread_object);
909 gdb::observers::thread_exit.attach (delete_thread_object);
910 gdb::observers::normal_stop.attach (python_on_normal_stop);
911 gdb::observers::target_resumed.attach (python_on_resume);
912 gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre);
913 gdb::observers::inferior_call_post.attach (python_on_inferior_call_post);
914 gdb::observers::memory_changed.attach (python_on_memory_change);
915 gdb::observers::register_changed.attach (python_on_register_change);
916 gdb::observers::inferior_exit.attach (python_inferior_exit);
917 gdb::observers::new_objfile.attach (python_new_objfile);
918 gdb::observers::inferior_added.attach (python_new_inferior);
919 gdb::observers::inferior_removed.attach (python_inferior_deleted);
920
921 membuf_object_type.tp_new = PyType_GenericNew;
922 if (PyType_Ready (&membuf_object_type) < 0)
923 return -1;
924
925 return gdb_pymodule_addobject (gdb_module, "Membuf",
926 (PyObject *) &membuf_object_type);
927 }
928
929 static gdb_PyGetSetDef inferior_object_getset[] =
930 {
931 { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
932 { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
933 NULL },
934 { "was_attached", infpy_get_was_attached, NULL,
935 "True if the inferior was created using 'attach'.", NULL },
936 { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
937 { NULL }
938 };
939
940 static PyMethodDef inferior_object_methods[] =
941 {
942 { "is_valid", infpy_is_valid, METH_NOARGS,
943 "is_valid () -> Boolean.\n\
944 Return true if this inferior is valid, false if not." },
945 { "threads", infpy_threads, METH_NOARGS,
946 "Return all the threads of this inferior." },
947 { "read_memory", (PyCFunction) infpy_read_memory,
948 METH_VARARGS | METH_KEYWORDS,
949 "read_memory (address, length) -> buffer\n\
950 Return a buffer object for reading from the inferior's memory." },
951 { "write_memory", (PyCFunction) infpy_write_memory,
952 METH_VARARGS | METH_KEYWORDS,
953 "write_memory (address, buffer [, length])\n\
954 Write the given buffer object to the inferior's memory." },
955 { "search_memory", (PyCFunction) infpy_search_memory,
956 METH_VARARGS | METH_KEYWORDS,
957 "search_memory (address, length, pattern) -> long\n\
958 Return a long with the address of a match, or None." },
959 /* thread_from_thread_handle is deprecated. */
960 { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
961 METH_VARARGS | METH_KEYWORDS,
962 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
963 Return thread object corresponding to thread handle.\n\
964 This method is deprecated - use thread_from_handle instead." },
965 { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
966 METH_VARARGS | METH_KEYWORDS,
967 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
968 Return thread object corresponding to thread handle." },
969 { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
970 "architecture () -> gdb.Architecture\n\
971 Return architecture of this inferior." },
972 { NULL }
973 };
974
975 PyTypeObject inferior_object_type =
976 {
977 PyVarObject_HEAD_INIT (NULL, 0)
978 "gdb.Inferior", /* tp_name */
979 sizeof (inferior_object), /* tp_basicsize */
980 0, /* tp_itemsize */
981 infpy_dealloc, /* tp_dealloc */
982 0, /* tp_print */
983 0, /* tp_getattr */
984 0, /* tp_setattr */
985 0, /* tp_compare */
986 infpy_repr, /* tp_repr */
987 0, /* tp_as_number */
988 0, /* tp_as_sequence */
989 0, /* tp_as_mapping */
990 0, /* tp_hash */
991 0, /* tp_call */
992 0, /* tp_str */
993 0, /* tp_getattro */
994 0, /* tp_setattro */
995 0, /* tp_as_buffer */
996 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */
997 "GDB inferior object", /* tp_doc */
998 0, /* tp_traverse */
999 0, /* tp_clear */
1000 0, /* tp_richcompare */
1001 0, /* tp_weaklistoffset */
1002 0, /* tp_iter */
1003 0, /* tp_iternext */
1004 inferior_object_methods, /* tp_methods */
1005 0, /* tp_members */
1006 inferior_object_getset, /* tp_getset */
1007 0, /* tp_base */
1008 0, /* tp_dict */
1009 0, /* tp_descr_get */
1010 0, /* tp_descr_set */
1011 0, /* tp_dictoffset */
1012 0, /* tp_init */
1013 0 /* tp_alloc */
1014 };
1015
1016 #ifdef IS_PY3K
1017
1018 static PyBufferProcs buffer_procs =
1019 {
1020 get_buffer
1021 };
1022
1023 #else
1024
1025 static PyBufferProcs buffer_procs = {
1026 get_read_buffer,
1027 get_write_buffer,
1028 get_seg_count,
1029 get_char_buffer
1030 };
1031 #endif /* IS_PY3K */
1032
1033 PyTypeObject membuf_object_type = {
1034 PyVarObject_HEAD_INIT (NULL, 0)
1035 "gdb.Membuf", /*tp_name*/
1036 sizeof (membuf_object), /*tp_basicsize*/
1037 0, /*tp_itemsize*/
1038 mbpy_dealloc, /*tp_dealloc*/
1039 0, /*tp_print*/
1040 0, /*tp_getattr*/
1041 0, /*tp_setattr*/
1042 0, /*tp_compare*/
1043 0, /*tp_repr*/
1044 0, /*tp_as_number*/
1045 0, /*tp_as_sequence*/
1046 0, /*tp_as_mapping*/
1047 0, /*tp_hash */
1048 0, /*tp_call*/
1049 mbpy_str, /*tp_str*/
1050 0, /*tp_getattro*/
1051 0, /*tp_setattro*/
1052 &buffer_procs, /*tp_as_buffer*/
1053 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1054 "GDB memory buffer object", /*tp_doc*/
1055 0, /* tp_traverse */
1056 0, /* tp_clear */
1057 0, /* tp_richcompare */
1058 0, /* tp_weaklistoffset */
1059 0, /* tp_iter */
1060 0, /* tp_iternext */
1061 0, /* tp_methods */
1062 0, /* tp_members */
1063 0, /* tp_getset */
1064 0, /* tp_base */
1065 0, /* tp_dict */
1066 0, /* tp_descr_get */
1067 0, /* tp_descr_set */
1068 0, /* tp_dictoffset */
1069 0, /* tp_init */
1070 0, /* tp_alloc */
1071 };
This page took 0.054158 seconds and 4 git commands to generate.