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