Import gdb 7.3 into vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / python / py-inferior.c
1 /* Python interface to inferiors.
2
3    Copyright (C) 2009, 2010, 2011 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 "exceptions.h"
22 #include "gdbcore.h"
23 #include "gdbthread.h"
24 #include "inferior.h"
25 #include "observer.h"
26 #include "python-internal.h"
27 #include "arch-utils.h"
28 #include "language.h"
29 #include "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 typedef struct
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 } inferior_object;
52
53 static PyTypeObject inferior_object_type;
54
55 static const struct inferior_data *infpy_inf_data_key;
56
57 typedef struct {
58   PyObject_HEAD
59   void *buffer;
60
61   /* These are kept just for mbpy_str.  */
62   CORE_ADDR addr;
63   CORE_ADDR length;
64 } membuf_object;
65
66 static PyTypeObject membuf_object_type;
67
68 /* Require that INFERIOR be a valid inferior ID.  */
69 #define INFPY_REQUIRE_VALID(Inferior)                           \
70   do {                                                          \
71     if (!Inferior->inferior)                                    \
72       {                                                         \
73         PyErr_SetString (PyExc_RuntimeError,                    \
74                          _("Inferior no longer exists."));      \
75         return NULL;                                            \
76       }                                                         \
77   } while (0)
78
79 static void
80 python_on_normal_stop (struct bpstats *bs, int print_frame)
81 {
82   struct cleanup *cleanup;
83   enum target_signal stop_signal;
84
85   if (!find_thread_ptid (inferior_ptid))
86       return;
87
88   stop_signal = inferior_thread ()->suspend.stop_signal;
89
90   cleanup = ensure_python_env (get_current_arch (), current_language);
91
92   if (emit_stop_event (bs, stop_signal) < 0)
93     gdbpy_print_stack ();
94
95   do_cleanups (cleanup);
96 }
97
98 static void
99 python_on_resume (ptid_t ptid)
100 {
101   struct cleanup *cleanup;
102
103   cleanup = ensure_python_env (target_gdbarch, current_language);
104
105   if (emit_continue_event (ptid) < 0)
106     gdbpy_print_stack ();
107
108   do_cleanups (cleanup);
109 }
110
111 static void
112 python_inferior_exit (struct inferior *inf)
113 {
114   struct cleanup *cleanup;
115   const LONGEST *exit_code = NULL;
116
117   cleanup = ensure_python_env (target_gdbarch, current_language);
118
119   if (inf->has_exit_code)
120     exit_code = &inf->exit_code;
121
122   if (emit_exited_event (exit_code) < 0)
123     gdbpy_print_stack ();
124
125   do_cleanups (cleanup);
126 }
127
128 /* Return a borrowed reference to the Python object of type Inferior
129    representing INFERIOR.  If the object has already been created,
130    return it,  otherwise, create it.  Return NULL on failure.  */
131 PyObject *
132 inferior_to_inferior_object (struct inferior *inferior)
133 {
134   inferior_object *inf_obj;
135
136   inf_obj = inferior_data (inferior, infpy_inf_data_key);
137   if (!inf_obj)
138     {
139       struct cleanup *cleanup;
140       cleanup = ensure_python_env (python_gdbarch, python_language);
141
142       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
143       if (!inf_obj)
144         {
145           do_cleanups (cleanup);
146           return NULL;
147         }
148
149       inf_obj->inferior = inferior;
150       inf_obj->threads = NULL;
151       inf_obj->nthreads = 0;
152
153       set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
154
155       do_cleanups (cleanup);
156     }
157
158   return (PyObject *) inf_obj;
159 }
160
161 /* Finds the Python Inferior object for the given PID.  Returns a
162    borrowed reference, or NULL if PID does not match any inferior
163    object.  */
164
165 PyObject *
166 find_inferior_object (int pid)
167 {
168   struct inflist_entry *p;
169   struct inferior *inf = find_inferior_pid (pid);
170
171   if (inf)
172     return inferior_to_inferior_object (inf);
173
174   return NULL;
175 }
176
177 thread_object *
178 find_thread_object (ptid_t ptid)
179 {
180   int pid;
181   struct threadlist_entry *thread;
182   PyObject *inf_obj;
183
184   pid = PIDGET (ptid);
185   if (pid == 0)
186     return NULL;
187
188   inf_obj = find_inferior_object (pid);
189
190   if (inf_obj)
191     for (thread = ((inferior_object *)inf_obj)->threads; thread;
192          thread = thread->next)
193       if (ptid_equal (thread->thread_obj->thread->ptid, ptid))
194         return thread->thread_obj;
195
196   return NULL;
197 }
198
199 static void
200 add_thread_object (struct thread_info *tp)
201 {
202   struct cleanup *cleanup;
203   thread_object *thread_obj;
204   inferior_object *inf_obj;
205   struct threadlist_entry *entry;
206
207   cleanup = ensure_python_env (python_gdbarch, python_language);
208
209   thread_obj = create_thread_object (tp);
210   if (!thread_obj)
211     {
212       gdbpy_print_stack ();
213       do_cleanups (cleanup);
214       return;
215     }
216
217   inf_obj = (inferior_object *) thread_obj->inf_obj;
218
219   entry = xmalloc (sizeof (struct threadlist_entry));
220   entry->thread_obj = thread_obj;
221   entry->next = inf_obj->threads;
222
223   inf_obj->threads = entry;
224   inf_obj->nthreads++;
225
226   do_cleanups (cleanup);
227 }
228
229 static void
230 delete_thread_object (struct thread_info *tp, int ignore)
231 {
232   struct cleanup *cleanup;
233   inferior_object *inf_obj;
234   thread_object *thread_obj;
235   struct threadlist_entry **entry, *tmp;
236
237   inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
238   if (!inf_obj)
239     return;
240
241   /* Find thread entry in its inferior's thread_list.  */
242   for (entry = &inf_obj->threads; *entry != NULL; entry =
243          &(*entry)->next)
244     if ((*entry)->thread_obj->thread == tp)
245       break;
246
247   if (!*entry)
248     return;
249
250   cleanup = ensure_python_env (python_gdbarch, python_language);
251
252   tmp = *entry;
253   tmp->thread_obj->thread = NULL;
254
255   *entry = (*entry)->next;
256   inf_obj->nthreads--;
257
258   Py_DECREF (tmp->thread_obj);
259   xfree (tmp);
260
261   do_cleanups (cleanup);
262 }
263
264 static PyObject *
265 infpy_threads (PyObject *self, PyObject *args)
266 {
267   int i;
268   struct threadlist_entry *entry;
269   inferior_object *inf_obj = (inferior_object *) self;
270   PyObject *tuple;
271
272   INFPY_REQUIRE_VALID (inf_obj);
273
274   tuple = PyTuple_New (inf_obj->nthreads);
275   if (!tuple)
276     return NULL;
277
278   for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
279        i++, entry = entry->next)
280     {
281       Py_INCREF (entry->thread_obj);
282       PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj);
283     }
284
285   return tuple;
286 }
287
288 static PyObject *
289 infpy_get_num (PyObject *self, void *closure)
290 {
291   inferior_object *inf = (inferior_object *) self;
292
293   INFPY_REQUIRE_VALID (inf);
294
295   return PyLong_FromLong (inf->inferior->num);
296 }
297
298 static PyObject *
299 infpy_get_pid (PyObject *self, void *closure)
300 {
301   inferior_object *inf = (inferior_object *) self;
302
303   INFPY_REQUIRE_VALID (inf);
304
305   return PyLong_FromLong (inf->inferior->pid);
306 }
307
308 static PyObject *
309 infpy_get_was_attached (PyObject *self, void *closure)
310 {
311   inferior_object *inf = (inferior_object *) self;
312
313   INFPY_REQUIRE_VALID (inf);
314   if (inf->inferior->attach_flag)
315     Py_RETURN_TRUE;
316   Py_RETURN_FALSE;
317 }
318
319 static int
320 build_inferior_list (struct inferior *inf, void *arg)
321 {
322   PyObject *list = arg;
323   PyObject *inferior = inferior_to_inferior_object (inf);
324
325   if (PyList_Append (list, inferior))
326     return 1;
327
328   return 0;
329 }
330
331 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
332    Returns a tuple of all inferiors.  */
333 PyObject *
334 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
335 {
336   int i = 0;
337   PyObject *list, *inferior;
338   struct inferior *inf;
339
340   list = PyList_New (0);
341   if (!list)
342     return NULL;
343
344   if (iterate_over_inferiors (build_inferior_list, list))
345     {
346       Py_DECREF (list);
347       return NULL;
348     }
349
350   return PyList_AsTuple (list);
351 }
352
353 /* Membuf and memory manipulation.  */
354
355 /* Implementation of gdb.read_memory (address, length).
356    Returns a Python buffer object with LENGTH bytes of the inferior's
357    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
358    with a python exception set.  */
359 static PyObject *
360 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
361 {
362   int error = 0;
363   CORE_ADDR addr, length;
364   void *buffer = NULL;
365   membuf_object *membuf_obj;
366   PyObject *addr_obj, *length_obj;
367   struct cleanup *cleanups;
368   volatile struct gdb_exception except;
369   static char *keywords[] = { "address", "length", NULL };
370
371   if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
372                                      &addr_obj, &length_obj))
373     return NULL;
374
375   cleanups = make_cleanup (null_cleanup, NULL);
376
377   TRY_CATCH (except, RETURN_MASK_ALL)
378     {
379       if (!get_addr_from_python (addr_obj, &addr)
380           || !get_addr_from_python (length_obj, &length))
381         {
382           error = 1;
383           break;
384         }
385
386       buffer = xmalloc (length);
387       make_cleanup (xfree, buffer);
388
389       read_memory (addr, buffer, length);
390     }
391   if (except.reason < 0)
392     {
393       do_cleanups (cleanups);
394       GDB_PY_HANDLE_EXCEPTION (except);
395     }
396
397   if (error)
398     {
399       do_cleanups (cleanups);
400       return NULL;
401     }
402
403   membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
404   if (membuf_obj == NULL)
405     {
406       PyErr_SetString (PyExc_MemoryError,
407                        _("Could not allocate memory buffer object."));
408       do_cleanups (cleanups);
409       return NULL;
410     }
411
412   discard_cleanups (cleanups);
413
414   membuf_obj->buffer = buffer;
415   membuf_obj->addr = addr;
416   membuf_obj->length = length;
417
418   return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
419                                        Py_END_OF_BUFFER);
420 }
421
422 /* Implementation of gdb.write_memory (address, buffer [, length]).
423    Writes the contents of BUFFER (a Python object supporting the read
424    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
425    bytes from BUFFER, or its entire contents if the argument is not
426    provided.  The function returns nothing.  Returns NULL on error, with
427    a python exception set.  */
428 static PyObject *
429 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
430 {
431   int buf_len, error = 0;
432   const char *buffer;
433   CORE_ADDR addr, length;
434   PyObject *addr_obj, *length_obj = NULL;
435   volatile struct gdb_exception except;
436   static char *keywords[] = { "address", "buffer", "length", NULL };
437
438
439   if (! PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords,
440                                      &addr_obj, &buffer, &buf_len,
441                                      &length_obj))
442     return NULL;
443
444   TRY_CATCH (except, RETURN_MASK_ALL)
445     {
446       if (!get_addr_from_python (addr_obj, &addr))
447         {
448           error = 1;
449           break;
450         }
451
452       if (!length_obj)
453         length = buf_len;
454       else if (!get_addr_from_python (length_obj, &length))
455         {
456           error = 1;
457           break;
458         }
459       write_memory (addr, buffer, length);
460     }
461   GDB_PY_HANDLE_EXCEPTION (except);
462
463   if (error)
464     return NULL;
465
466   Py_RETURN_NONE;
467 }
468
469 /* Destructor of Membuf objects.  */
470 static void
471 mbpy_dealloc (PyObject *self)
472 {
473   xfree (((membuf_object *) self)->buffer);
474   self->ob_type->tp_free (self);
475 }
476
477 /* Return a description of the Membuf object.  */
478 static PyObject *
479 mbpy_str (PyObject *self)
480 {
481   membuf_object *membuf_obj = (membuf_object *) self;
482
483   return PyString_FromFormat (_("Memory buffer for address %s, \
484 which is %s bytes long."),
485                               paddress (python_gdbarch, membuf_obj->addr),
486                               pulongest (membuf_obj->length));
487 }
488
489 static Py_ssize_t
490 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
491 {
492   membuf_object *membuf_obj = (membuf_object *) self;
493
494   if (segment)
495     {
496       PyErr_SetString (PyExc_SystemError,
497                        _("The memory buffer supports only one segment."));
498       return -1;
499     }
500
501   *ptrptr = membuf_obj->buffer;
502
503   return membuf_obj->length;
504 }
505
506 static Py_ssize_t
507 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
508 {
509   return get_read_buffer (self, segment, ptrptr);
510 }
511
512 static Py_ssize_t
513 get_seg_count (PyObject *self, Py_ssize_t *lenp)
514 {
515   if (lenp)
516     *lenp = ((membuf_object *) self)->length;
517
518   return 1;
519 }
520
521 static Py_ssize_t
522 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
523 {
524   void *ptr = NULL;
525   Py_ssize_t ret;
526
527   ret = get_read_buffer (self, segment, &ptr);
528   *ptrptr = (char *) ptr;
529
530   return ret;
531 }
532
533 /* Implementation of
534    gdb.search_memory (address, length, pattern).  ADDRESS is the
535    address to start the search.  LENGTH specifies the scope of the
536    search from ADDRESS.  PATTERN is the pattern to search for (and
537    must be a Python object supporting the buffer protocol).
538    Returns a Python Long object holding the address where the pattern
539    was located, or if the pattern was not found, returns None.  Returns NULL
540    on error, with a python exception set.  */
541 static PyObject *
542 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
543 {
544   CORE_ADDR start_addr, length;
545   static char *keywords[] = { "address", "length", "pattern", NULL };
546   PyObject *pattern, *start_addr_obj, *length_obj;
547   volatile struct gdb_exception except;
548   Py_ssize_t pattern_size;
549   const void *buffer;
550   CORE_ADDR found_addr;
551   int found = 0;
552
553   if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
554                                      &start_addr_obj, &length_obj,
555                                      &pattern))
556     return NULL;
557
558   if (get_addr_from_python (start_addr_obj, &start_addr)
559       && get_addr_from_python (length_obj, &length))
560     {
561       if (!length)
562         {
563           PyErr_SetString (PyExc_ValueError,
564                            _("Search range is empty."));
565           return NULL;
566         }
567       /* Watch for overflows.  */
568       else if (length > CORE_ADDR_MAX
569                || (start_addr + length - 1) < start_addr)
570         {
571           PyErr_SetString (PyExc_ValueError,
572                            _("The search range is too large."));
573
574           return NULL;
575         }
576     }
577   else
578     return NULL;
579
580   if (!PyObject_CheckReadBuffer (pattern))
581     {
582       PyErr_SetString (PyExc_RuntimeError,
583                        _("The pattern is not a Python buffer."));
584
585       return NULL;
586     }
587
588   if (PyObject_AsReadBuffer (pattern, &buffer, &pattern_size) == -1)
589     return NULL;
590
591   TRY_CATCH (except, RETURN_MASK_ALL)
592     {
593       found = target_search_memory (start_addr, length,
594                                     buffer, pattern_size,
595                                     &found_addr);
596     }
597   GDB_PY_HANDLE_EXCEPTION (except);
598
599   if (found)
600     return PyLong_FromLong (found_addr);
601   else
602     Py_RETURN_NONE;
603 }
604
605 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
606    Returns True if this inferior object still exists in GDB.  */
607
608 static PyObject *
609 infpy_is_valid (PyObject *self, PyObject *args)
610 {
611   inferior_object *inf = (inferior_object *) self;
612
613   if (! inf->inferior)
614     Py_RETURN_FALSE;
615
616   Py_RETURN_TRUE;
617 }
618
619
620 /* Clear the INFERIOR pointer in an Inferior object and clear the
621    thread list.  */
622 static void
623 py_free_inferior (struct inferior *inf, void *datum)
624 {
625
626   struct cleanup *cleanup;
627   inferior_object *inf_obj = datum;
628   struct threadlist_entry *th_entry, *th_tmp;
629
630   cleanup = ensure_python_env (python_gdbarch, python_language);
631
632   inf_obj->inferior = NULL;
633
634   /* Deallocate threads list.  */
635   for (th_entry = inf_obj->threads; th_entry != NULL;)
636     {
637       Py_DECREF (th_entry->thread_obj);
638
639       th_tmp = th_entry;
640       th_entry = th_entry->next;
641       xfree (th_tmp);
642     }
643
644   inf_obj->nthreads = 0;
645
646   Py_DECREF ((PyObject *) inf_obj);
647   do_cleanups (cleanup);
648 }
649
650 void
651 gdbpy_initialize_inferior (void)
652 {
653   if (PyType_Ready (&inferior_object_type) < 0)
654     return;
655
656   Py_INCREF (&inferior_object_type);
657   PyModule_AddObject (gdb_module, "Inferior",
658                       (PyObject *) &inferior_object_type);
659
660   infpy_inf_data_key =
661     register_inferior_data_with_cleanup (py_free_inferior);
662
663   observer_attach_new_thread (add_thread_object);
664   observer_attach_thread_exit (delete_thread_object);
665   observer_attach_normal_stop (python_on_normal_stop);
666   observer_attach_target_resumed (python_on_resume);
667   observer_attach_inferior_exit (python_inferior_exit);
668
669   if (PyType_Ready (&membuf_object_type) < 0)
670     return;
671
672   Py_INCREF (&membuf_object_type);
673   PyModule_AddObject (gdb_module, "Membuf", (PyObject *)
674                       &membuf_object_type);
675 }
676
677 static PyGetSetDef inferior_object_getset[] =
678 {
679   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
680   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
681     NULL },
682   { "was_attached", infpy_get_was_attached, NULL,
683     "True if the inferior was created using 'attach'.", NULL },
684   { NULL }
685 };
686
687 static PyMethodDef inferior_object_methods[] =
688 {
689   { "is_valid", infpy_is_valid, METH_NOARGS,
690     "is_valid () -> Boolean.\n\
691 Return true if this inferior is valid, false if not." },
692   { "threads", infpy_threads, METH_NOARGS,
693     "Return all the threads of this inferior." },
694   { "read_memory", (PyCFunction) infpy_read_memory,
695     METH_VARARGS | METH_KEYWORDS,
696     "read_memory (address, length) -> buffer\n\
697 Return a buffer object for reading from the inferior's memory." },
698   { "write_memory", (PyCFunction) infpy_write_memory,
699     METH_VARARGS | METH_KEYWORDS,
700     "write_memory (address, buffer [, length])\n\
701 Write the given buffer object to the inferior's memory." },
702   { "search_memory", (PyCFunction) infpy_search_memory,
703     METH_VARARGS | METH_KEYWORDS,
704     "search_memory (address, length, pattern) -> long\n\
705 Return a long with the address of a match, or None." },
706   { NULL }
707 };
708
709 static PyTypeObject inferior_object_type =
710 {
711   PyObject_HEAD_INIT (NULL)
712   0,                              /* ob_size */
713   "gdb.Inferior",                 /* tp_name */
714   sizeof (inferior_object),       /* tp_basicsize */
715   0,                              /* tp_itemsize */
716   0,                              /* tp_dealloc */
717   0,                              /* tp_print */
718   0,                              /* tp_getattr */
719   0,                              /* tp_setattr */
720   0,                              /* tp_compare */
721   0,                              /* tp_repr */
722   0,                              /* tp_as_number */
723   0,                              /* tp_as_sequence */
724   0,                              /* tp_as_mapping */
725   0,                              /* tp_hash  */
726   0,                              /* tp_call */
727   0,                              /* tp_str */
728   0,                              /* tp_getattro */
729   0,                              /* tp_setattro */
730   0,                              /* tp_as_buffer */
731   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /* tp_flags */
732   "GDB inferior object",          /* tp_doc */
733   0,                              /* tp_traverse */
734   0,                              /* tp_clear */
735   0,                              /* tp_richcompare */
736   0,                              /* tp_weaklistoffset */
737   0,                              /* tp_iter */
738   0,                              /* tp_iternext */
739   inferior_object_methods,        /* tp_methods */
740   0,                              /* tp_members */
741   inferior_object_getset,         /* tp_getset */
742   0,                              /* tp_base */
743   0,                              /* tp_dict */
744   0,                              /* tp_descr_get */
745   0,                              /* tp_descr_set */
746   0,                              /* tp_dictoffset */
747   0,                              /* tp_init */
748   0                               /* tp_alloc */
749 };
750
751 /* Python doesn't provide a decent way to get compatibility here.  */
752 #if HAVE_LIBPYTHON2_4
753 #define CHARBUFFERPROC_NAME getcharbufferproc
754 #else
755 #define CHARBUFFERPROC_NAME charbufferproc
756 #endif
757
758 static PyBufferProcs buffer_procs = {
759   get_read_buffer,
760   get_write_buffer,
761   get_seg_count,
762   /* The cast here works around a difference between Python 2.4 and
763      Python 2.5.  */
764   (CHARBUFFERPROC_NAME) get_char_buffer
765 };
766
767 static PyTypeObject membuf_object_type = {
768   PyObject_HEAD_INIT (NULL)
769   0,                              /*ob_size*/
770   "gdb.Membuf",                   /*tp_name*/
771   sizeof (membuf_object),         /*tp_basicsize*/
772   0,                              /*tp_itemsize*/
773   mbpy_dealloc,                   /*tp_dealloc*/
774   0,                              /*tp_print*/
775   0,                              /*tp_getattr*/
776   0,                              /*tp_setattr*/
777   0,                              /*tp_compare*/
778   0,                              /*tp_repr*/
779   0,                              /*tp_as_number*/
780   0,                              /*tp_as_sequence*/
781   0,                              /*tp_as_mapping*/
782   0,                              /*tp_hash */
783   0,                              /*tp_call*/
784   mbpy_str,                       /*tp_str*/
785   0,                              /*tp_getattro*/
786   0,                              /*tp_setattro*/
787   &buffer_procs,                  /*tp_as_buffer*/
788   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
789   "GDB memory buffer object",     /*tp_doc*/
790   0,                              /* tp_traverse */
791   0,                              /* tp_clear */
792   0,                              /* tp_richcompare */
793   0,                              /* tp_weaklistoffset */
794   0,                              /* tp_iter */
795   0,                              /* tp_iternext */
796   0,                              /* tp_methods */
797   0,                              /* tp_members */
798   0,                              /* tp_getset */
799   0,                              /* tp_base */
800   0,                              /* tp_dict */
801   0,                              /* tp_descr_get */
802   0,                              /* tp_descr_set */
803   0,                              /* tp_dictoffset */
804   0,                              /* tp_init */
805   0,                              /* tp_alloc */
806   PyType_GenericNew               /* tp_new */
807 };