gdb/
[deliverable/binutils-gdb.git] / gdb / python / py-inferior.c
CommitLineData
595939de
PM
1/* Python interface to inferiors.
2
7b6bb8da 3 Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
595939de
PM
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"
505500db
SW
29#include "gdb_signals.h"
30#include "py-event.h"
31#include "py-stopevent.h"
595939de
PM
32
33struct threadlist_entry {
34 thread_object *thread_obj;
35 struct threadlist_entry *next;
36};
37
38typedef 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
53static PyTypeObject inferior_object_type;
54
55static const struct inferior_data *infpy_inf_data_key;
56
57typedef 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
66static 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
505500db
SW
79static void
80python_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
98static void
99python_on_resume (ptid_t ptid)
100{
101 struct cleanup *cleanup;
102
310afc76 103 cleanup = ensure_python_env (target_gdbarch, current_language);
505500db
SW
104
105 if (emit_continue_event (ptid) < 0)
106 gdbpy_print_stack ();
107
108 do_cleanups (cleanup);
109}
110
111static void
112python_inferior_exit (struct inferior *inf)
113{
114 struct cleanup *cleanup;
8cf64490 115 const LONGEST *exit_code = NULL;
505500db 116
310afc76 117 cleanup = ensure_python_env (target_gdbarch, current_language);
505500db 118
8cf64490
TT
119 if (inf->has_exit_code)
120 exit_code = &inf->exit_code;
505500db 121
8cf64490 122 if (emit_exited_event (exit_code) < 0)
505500db
SW
123 gdbpy_print_stack ();
124
125 do_cleanups (cleanup);
126}
127
595939de
PM
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. */
131PyObject *
132inferior_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
505500db
SW
163 object. */
164
595939de
PM
165PyObject *
166find_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
177thread_object *
178find_thread_object (ptid_t ptid)
179{
180 int pid;
181 struct threadlist_entry *thread;
182 PyObject *inf_obj;
183
184 pid = PIDGET (ptid);
ea976c60
PM
185 if (pid == 0)
186 return NULL;
187
595939de
PM
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
199static void
200add_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
229static void
230delete_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
264static PyObject *
265infpy_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
288static PyObject *
289infpy_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
298static PyObject *
299infpy_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
308static PyObject *
309infpy_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
319static int
320build_inferior_list (struct inferior *inf, void *arg)
321{
322 PyObject *list = arg;
323 PyObject *inferior = inferior_to_inferior_object (inf);
324
2d565757
MS
325 if (PyList_Append (list, inferior))
326 return 1;
327
595939de
PM
328 return 0;
329}
330
331/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
332 Returns a tuple of all inferiors. */
333PyObject *
334gdbpy_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
2d565757
MS
344 if (iterate_over_inferiors (build_inferior_list, list))
345 {
346 Py_DECREF (list);
347 return NULL;
348 }
595939de
PM
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
8dc78533
JK
357 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
358 with a python exception set. */
595939de
PM
359static PyObject *
360infpy_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
8dc78533
JK
426 provided. The function returns nothing. Returns NULL on error, with
427 a python exception set. */
595939de
PM
428static PyObject *
429infpy_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. */
470static void
471mbpy_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. */
478static PyObject *
479mbpy_str (PyObject *self)
480{
481 membuf_object *membuf_obj = (membuf_object *) self;
482
483 return PyString_FromFormat (_("Memory buffer for address %s, \
484which is %s bytes long."),
485 paddress (python_gdbarch, membuf_obj->addr),
486 pulongest (membuf_obj->length));
487}
488
489static Py_ssize_t
490get_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
506static Py_ssize_t
507get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
508{
509 return get_read_buffer (self, segment, ptrptr);
510}
511
512static Py_ssize_t
513get_seg_count (PyObject *self, Py_ssize_t *lenp)
514{
515 if (lenp)
516 *lenp = ((membuf_object *) self)->length;
517
518 return 1;
519}
520
521static Py_ssize_t
522get_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
8dc78533
JK
539 was located, or if the pattern was not found, returns None. Returns NULL
540 on error, with a python exception set. */
595939de
PM
541static PyObject *
542infpy_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
8dc78533 578 return NULL;
595939de
PM
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
29703da4
PM
605/* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
606 Returns True if this inferior object still exists in GDB. */
607
608static PyObject *
609infpy_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
595939de
PM
619
620/* Clear the INFERIOR pointer in an Inferior object and clear the
621 thread list. */
622static void
623py_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
650void
651gdbpy_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);
505500db
SW
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);
595939de
PM
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
677static 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
687static PyMethodDef inferior_object_methods[] =
688{
29703da4
PM
689 { "is_valid", infpy_is_valid, METH_NOARGS,
690 "is_valid () -> Boolean.\n\
691Return true if this inferior is valid, false if not." },
595939de
PM
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\
697Return 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\
701Write 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\
705Return a long with the address of a match, or None." },
706 { NULL }
707};
708
709static 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
758static 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
767static 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};
This page took 0.148681 seconds and 4 git commands to generate.