1 /* Python interface to stack frames
2
3 Copyright (C) 2008-2013 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 "charset.h"
22 #include "block.h"
23 #include "frame.h"
24 #include "exceptions.h"
25 #include "symtab.h"
26 #include "stack.h"
27 #include "value.h"
28 #include "python-internal.h"
29 #include "symfile.h"
30 #include "objfiles.h"
31
32 typedef struct {
33 PyObject_HEAD
34 struct frame_id frame_id;
35 struct gdbarch *gdbarch;
36
37 /* Marks that the FRAME_ID member actually holds the ID of the frame next
38 to this, and not this frames' ID itself. This is a hack to permit Python
39 frame objects which represent invalid frames (i.e., the last frame_info
40 in a corrupt stack). The problem arises from the fact that this code
41 relies on FRAME_ID to uniquely identify a frame, which is not always true
42 for the last "frame" in a corrupt stack (it can have a null ID, or the same
43 ID as the previous frame). Whenever get_prev_frame returns NULL, we
44 record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */
45 int frame_id_is_next;
46 } frame_object;
47
48 /* Require a valid frame. This must be called inside a TRY_CATCH, or
49 another context in which a gdb exception is allowed. */
50 #define FRAPY_REQUIRE_VALID(frame_obj, frame) \
51 do { \
52 frame = frame_object_to_frame_info (frame_obj); \
53 if (frame == NULL) \
54 error (_("Frame is invalid.")); \
55 } while (0)
56
57 /* Returns the frame_info object corresponding to the given Python Frame
58 object. If the frame doesn't exist anymore (the frame id doesn't
59 correspond to any frame in the inferior), returns NULL. */
60
61 struct frame_info *
frame_object_to_frame_info(PyObject * obj)62 frame_object_to_frame_info (PyObject *obj)
63 {
64 frame_object *frame_obj = (frame_object *) obj;
65 struct frame_info *frame;
66
67 frame = frame_find_by_id (frame_obj->frame_id);
68 if (frame == NULL)
69 return NULL;
70
71 if (frame_obj->frame_id_is_next)
72 frame = get_prev_frame (frame);
73
74 return frame;
75 }
76
77 /* Called by the Python interpreter to obtain string representation
78 of the object. */
79
80 static PyObject *
frapy_str(PyObject * self)81 frapy_str (PyObject *self)
82 {
83 char *s;
84 PyObject *result;
85 struct ui_file *strfile;
86
87 strfile = mem_fileopen ();
88 fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
89 s = ui_file_xstrdup (strfile, NULL);
90 result = PyString_FromString (s);
91 xfree (s);
92
93 return result;
94 }
95
96 /* Implementation of gdb.Frame.is_valid (self) -> Boolean.
97 Returns True if the frame corresponding to the frame_id of this
98 object still exists in the inferior. */
99
100 static PyObject *
frapy_is_valid(PyObject * self,PyObject * args)101 frapy_is_valid (PyObject *self, PyObject *args)
102 {
103 struct frame_info *frame = NULL;
104 volatile struct gdb_exception except;
105
106 TRY_CATCH (except, RETURN_MASK_ALL)
107 {
108 frame = frame_object_to_frame_info (self);
109 }
110 GDB_PY_HANDLE_EXCEPTION (except);
111
112 if (frame == NULL)
113 Py_RETURN_FALSE;
114
115 Py_RETURN_TRUE;
116 }
117
118 /* Implementation of gdb.Frame.name (self) -> String.
119 Returns the name of the function corresponding to this frame. */
120
121 static PyObject *
frapy_name(PyObject * self,PyObject * args)122 frapy_name (PyObject *self, PyObject *args)
123 {
124 struct frame_info *frame;
125 const char *name;
126 enum language lang;
127 PyObject *result;
128 volatile struct gdb_exception except;
129
130 TRY_CATCH (except, RETURN_MASK_ALL)
131 {
132 FRAPY_REQUIRE_VALID (self, frame);
133
134 find_frame_funname (frame, &name, &lang, NULL);
135 }
136 GDB_PY_HANDLE_EXCEPTION (except);
137
138 if (name)
139 result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
140 else
141 {
142 result = Py_None;
143 Py_INCREF (Py_None);
144 }
145
146 return result;
147 }
148
149 /* Implementation of gdb.Frame.type (self) -> Integer.
150 Returns the frame type, namely one of the gdb.*_FRAME constants. */
151
152 static PyObject *
frapy_type(PyObject * self,PyObject * args)153 frapy_type (PyObject *self, PyObject *args)
154 {
155 struct frame_info *frame;
156 enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */
157 volatile struct gdb_exception except;
158
159 TRY_CATCH (except, RETURN_MASK_ALL)
160 {
161 FRAPY_REQUIRE_VALID (self, frame);
162
163 type = get_frame_type (frame);
164 }
165 GDB_PY_HANDLE_EXCEPTION (except);
166
167 return PyInt_FromLong (type);
168 }
169
170 /* Implementation of gdb.Frame.architecture (self) -> gdb.Architecture.
171 Returns the frame's architecture as a gdb.Architecture object. */
172
173 static PyObject *
frapy_arch(PyObject * self,PyObject * args)174 frapy_arch (PyObject *self, PyObject *args)
175 {
176 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
177 frame_object *obj = (frame_object *) self;
178 volatile struct gdb_exception except;
179
180 TRY_CATCH (except, RETURN_MASK_ALL)
181 {
182 FRAPY_REQUIRE_VALID (self, frame);
183 }
184 GDB_PY_HANDLE_EXCEPTION (except);
185
186 return gdbarch_to_arch_object (obj->gdbarch);
187 }
188
189 /* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
190 Returns one of the gdb.FRAME_UNWIND_* constants. */
191
192 static PyObject *
frapy_unwind_stop_reason(PyObject * self,PyObject * args)193 frapy_unwind_stop_reason (PyObject *self, PyObject *args)
194 {
195 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
196 volatile struct gdb_exception except;
197 enum unwind_stop_reason stop_reason;
198
199 TRY_CATCH (except, RETURN_MASK_ALL)
200 {
201 FRAPY_REQUIRE_VALID (self, frame);
202 }
203 GDB_PY_HANDLE_EXCEPTION (except);
204
205 stop_reason = get_frame_unwind_stop_reason (frame);
206
207 return PyInt_FromLong (stop_reason);
208 }
209
210 /* Implementation of gdb.Frame.pc (self) -> Long.
211 Returns the frame's resume address. */
212
213 static PyObject *
frapy_pc(PyObject * self,PyObject * args)214 frapy_pc (PyObject *self, PyObject *args)
215 {
216 CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */
217 struct frame_info *frame;
218 volatile struct gdb_exception except;
219
220 TRY_CATCH (except, RETURN_MASK_ALL)
221 {
222 FRAPY_REQUIRE_VALID (self, frame);
223
224 pc = get_frame_pc (frame);
225 }
226 GDB_PY_HANDLE_EXCEPTION (except);
227
228 return gdb_py_long_from_ulongest (pc);
229 }
230
231 /* Implementation of gdb.Frame.block (self) -> gdb.Block.
232 Returns the frame's code block. */
233
234 static PyObject *
frapy_block(PyObject * self,PyObject * args)235 frapy_block (PyObject *self, PyObject *args)
236 {
237 struct frame_info *frame;
238 struct block *block = NULL, *fn_block;
239 volatile struct gdb_exception except;
240
241 TRY_CATCH (except, RETURN_MASK_ALL)
242 {
243 FRAPY_REQUIRE_VALID (self, frame);
244 block = get_frame_block (frame, NULL);
245 }
246 GDB_PY_HANDLE_EXCEPTION (except);
247
248 for (fn_block = block;
249 fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
250 fn_block = BLOCK_SUPERBLOCK (fn_block))
251 ;
252
253 if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
254 {
255 PyErr_SetString (PyExc_RuntimeError,
256 _("Cannot locate object file for block."));
257 return NULL;
258 }
259
260 if (block)
261 {
262 struct symtab *symt;
263
264 symt = SYMBOL_SYMTAB (BLOCK_FUNCTION (fn_block));
265 return block_to_block_object (block, symt->objfile);
266 }
267
268 Py_RETURN_NONE;
269 }
270
271
272 /* Implementation of gdb.Frame.function (self) -> gdb.Symbol.
273 Returns the symbol for the function corresponding to this frame. */
274
275 static PyObject *
frapy_function(PyObject * self,PyObject * args)276 frapy_function (PyObject *self, PyObject *args)
277 {
278 struct symbol *sym = NULL;
279 struct frame_info *frame;
280 volatile struct gdb_exception except;
281
282 TRY_CATCH (except, RETURN_MASK_ALL)
283 {
284 FRAPY_REQUIRE_VALID (self, frame);
285
286 sym = find_pc_function (get_frame_address_in_block (frame));
287 }
288 GDB_PY_HANDLE_EXCEPTION (except);
289
290 if (sym)
291 return symbol_to_symbol_object (sym);
292
293 Py_RETURN_NONE;
294 }
295
296 /* Convert a frame_info struct to a Python Frame object.
297 Sets a Python exception and returns NULL on error. */
298
299 PyObject *
frame_info_to_frame_object(struct frame_info * frame)300 frame_info_to_frame_object (struct frame_info *frame)
301 {
302 frame_object *frame_obj;
303 volatile struct gdb_exception except;
304
305 frame_obj = PyObject_New (frame_object, &frame_object_type);
306 if (frame_obj == NULL)
307 {
308 PyErr_SetString (PyExc_MemoryError,
309 _("Could not allocate frame object."));
310 return NULL;
311 }
312
313 TRY_CATCH (except, RETURN_MASK_ALL)
314 {
315
316 /* Try to get the previous frame, to determine if this is the last frame
317 in a corrupt stack. If so, we need to store the frame_id of the next
318 frame and not of this one (which is possibly invalid). */
319 if (get_prev_frame (frame) == NULL
320 && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
321 && get_next_frame (frame) != NULL)
322 {
323 frame_obj->frame_id = get_frame_id (get_next_frame (frame));
324 frame_obj->frame_id_is_next = 1;
325 }
326 else
327 {
328 frame_obj->frame_id = get_frame_id (frame);
329 frame_obj->frame_id_is_next = 0;
330 }
331 frame_obj->gdbarch = get_frame_arch (frame);
332 }
333 GDB_PY_HANDLE_EXCEPTION (except);
334
335 return (PyObject *) frame_obj;
336 }
337
338 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
339 Returns the frame immediately older (outer) to this frame, or None if
340 there isn't one. */
341
342 static PyObject *
frapy_older(PyObject * self,PyObject * args)343 frapy_older (PyObject *self, PyObject *args)
344 {
345 struct frame_info *frame, *prev;
346 volatile struct gdb_exception except;
347 PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */
348
349 TRY_CATCH (except, RETURN_MASK_ALL)
350 {
351 FRAPY_REQUIRE_VALID (self, frame);
352
353 prev = get_prev_frame (frame);
354 if (prev)
355 prev_obj = (PyObject *) frame_info_to_frame_object (prev);
356 else
357 {
358 Py_INCREF (Py_None);
359 prev_obj = Py_None;
360 }
361 }
362 GDB_PY_HANDLE_EXCEPTION (except);
363
364 return prev_obj;
365 }
366
367 /* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
368 Returns the frame immediately newer (inner) to this frame, or None if
369 there isn't one. */
370
371 static PyObject *
frapy_newer(PyObject * self,PyObject * args)372 frapy_newer (PyObject *self, PyObject *args)
373 {
374 struct frame_info *frame, *next;
375 volatile struct gdb_exception except;
376 PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */
377
378 TRY_CATCH (except, RETURN_MASK_ALL)
379 {
380 FRAPY_REQUIRE_VALID (self, frame);
381
382 next = get_next_frame (frame);
383 if (next)
384 next_obj = (PyObject *) frame_info_to_frame_object (next);
385 else
386 {
387 Py_INCREF (Py_None);
388 next_obj = Py_None;
389 }
390 }
391 GDB_PY_HANDLE_EXCEPTION (except);
392
393 return next_obj;
394 }
395
396 /* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
397 Returns the frame's symtab and line. */
398
399 static PyObject *
frapy_find_sal(PyObject * self,PyObject * args)400 frapy_find_sal (PyObject *self, PyObject *args)
401 {
402 struct frame_info *frame;
403 struct symtab_and_line sal;
404 volatile struct gdb_exception except;
405 PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */
406
407 TRY_CATCH (except, RETURN_MASK_ALL)
408 {
409 FRAPY_REQUIRE_VALID (self, frame);
410
411 find_frame_sal (frame, &sal);
412 sal_obj = symtab_and_line_to_sal_object (sal);
413 }
414 GDB_PY_HANDLE_EXCEPTION (except);
415
416 return sal_obj;
417 }
418
419 /* Implementation of gdb.Frame.read_var_value (self, variable,
420 [block]) -> gdb.Value. If the optional block argument is provided
421 start the search from that block, otherwise search from the frame's
422 current block (determined by examining the resume address of the
423 frame). The variable argument must be a string or an instance of a
424 gdb.Symbol. The block argument must be an instance of gdb.Block. Returns
425 NULL on error, with a python exception set. */
426 static PyObject *
frapy_read_var(PyObject * self,PyObject * args)427 frapy_read_var (PyObject *self, PyObject *args)
428 {
429 struct frame_info *frame;
430 PyObject *sym_obj, *block_obj = NULL;
431 struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
432 struct value *val = NULL;
433 volatile struct gdb_exception except;
434
435 if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
436 return NULL;
437
438 if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
439 var = symbol_object_to_symbol (sym_obj);
440 else if (gdbpy_is_string (sym_obj))
441 {
442 char *var_name;
443 const struct block *block = NULL;
444 struct cleanup *cleanup;
445 volatile struct gdb_exception except;
446
447 var_name = python_string_to_target_string (sym_obj);
448 if (!var_name)
449 return NULL;
450 cleanup = make_cleanup (xfree, var_name);
451
452 if (block_obj)
453 {
454 block = block_object_to_block (block_obj);
455 if (!block)
456 {
457 PyErr_SetString (PyExc_RuntimeError,
458 _("Second argument must be block."));
459 return NULL;
460 }
461 }
462
463 TRY_CATCH (except, RETURN_MASK_ALL)
464 {
465 FRAPY_REQUIRE_VALID (self, frame);
466
467 if (!block)
468 block = get_frame_block (frame, NULL);
469 var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
470 }
471 GDB_PY_HANDLE_EXCEPTION (except);
472
473 if (!var)
474 {
475 PyErr_Format (PyExc_ValueError,
476 _("Variable '%s' not found."), var_name);
477 do_cleanups (cleanup);
478
479 return NULL;
480 }
481
482 do_cleanups (cleanup);
483 }
484 else
485 {
486 PyErr_SetString (PyExc_TypeError,
487 _("Argument must be a symbol or string."));
488 return NULL;
489 }
490
491 TRY_CATCH (except, RETURN_MASK_ALL)
492 {
493 FRAPY_REQUIRE_VALID (self, frame);
494
495 val = read_var_value (var, frame);
496 }
497 GDB_PY_HANDLE_EXCEPTION (except);
498
499 return value_to_value_object (val);
500 }
501
502 /* Select this frame. */
503
504 static PyObject *
frapy_select(PyObject * self,PyObject * args)505 frapy_select (PyObject *self, PyObject *args)
506 {
507 struct frame_info *fi;
508 volatile struct gdb_exception except;
509
510 TRY_CATCH (except, RETURN_MASK_ALL)
511 {
512 FRAPY_REQUIRE_VALID (self, fi);
513
514 select_frame (fi);
515 }
516 GDB_PY_HANDLE_EXCEPTION (except);
517
518 Py_RETURN_NONE;
519 }
520
521 /* Implementation of gdb.newest_frame () -> gdb.Frame.
522 Returns the newest frame object. */
523
524 PyObject *
gdbpy_newest_frame(PyObject * self,PyObject * args)525 gdbpy_newest_frame (PyObject *self, PyObject *args)
526 {
527 struct frame_info *frame;
528 PyObject *frame_obj = NULL; /* Initialize to appease gcc warning. */
529 volatile struct gdb_exception except;
530
531 TRY_CATCH (except, RETURN_MASK_ALL)
532 {
533 frame = get_current_frame ();
534 frame_obj = frame_info_to_frame_object (frame);
535 }
536 GDB_PY_HANDLE_EXCEPTION (except);
537
538 return frame_obj;
539 }
540
541 /* Implementation of gdb.selected_frame () -> gdb.Frame.
542 Returns the selected frame object. */
543
544 PyObject *
gdbpy_selected_frame(PyObject * self,PyObject * args)545 gdbpy_selected_frame (PyObject *self, PyObject *args)
546 {
547 struct frame_info *frame;
548 PyObject *frame_obj = NULL; /* Initialize to appease gcc warning. */
549 volatile struct gdb_exception except;
550
551 TRY_CATCH (except, RETURN_MASK_ALL)
552 {
553 frame = get_selected_frame ("No frame is currently selected.");
554 frame_obj = frame_info_to_frame_object (frame);
555 }
556 GDB_PY_HANDLE_EXCEPTION (except);
557
558 return frame_obj;
559 }
560
561 /* Implementation of gdb.stop_reason_string (Integer) -> String.
562 Return a string explaining the unwind stop reason. */
563
564 PyObject *
gdbpy_frame_stop_reason_string(PyObject * self,PyObject * args)565 gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
566 {
567 int reason;
568 const char *str;
569
570 if (!PyArg_ParseTuple (args, "i", &reason))
571 return NULL;
572
573 if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
574 {
575 PyErr_SetString (PyExc_ValueError,
576 _("Invalid frame stop reason."));
577 return NULL;
578 }
579
580 str = frame_stop_reason_string (reason);
581 return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
582 }
583
584 /* Implements the equality comparison for Frame objects.
585 All other comparison operators will throw a TypeError Python exception,
586 as they aren't valid for frames. */
587
588 static PyObject *
frapy_richcompare(PyObject * self,PyObject * other,int op)589 frapy_richcompare (PyObject *self, PyObject *other, int op)
590 {
591 int result;
592
593 if (!PyObject_TypeCheck (other, &frame_object_type)
594 || (op != Py_EQ && op != Py_NE))
595 {
596 Py_INCREF (Py_NotImplemented);
597 return Py_NotImplemented;
598 }
599
600 if (frame_id_eq (((frame_object *) self)->frame_id,
601 ((frame_object *) other)->frame_id))
602 result = Py_EQ;
603 else
604 result = Py_NE;
605
606 if (op == result)
607 Py_RETURN_TRUE;
608 Py_RETURN_FALSE;
609 }
610
611 /* Sets up the Frame API in the gdb module. */
612
613 void
gdbpy_initialize_frames(void)614 gdbpy_initialize_frames (void)
615 {
616 frame_object_type.tp_new = PyType_GenericNew;
617 if (PyType_Ready (&frame_object_type) < 0)
618 return;
619
620 /* Note: These would probably be best exposed as class attributes of
621 Frame, but I don't know how to do it except by messing with the
622 type's dictionary. That seems too messy. */
623 PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME);
624 PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME);
625 PyModule_AddIntConstant (gdb_module, "INLINE_FRAME", INLINE_FRAME);
626 PyModule_AddIntConstant (gdb_module, "TAILCALL_FRAME", TAILCALL_FRAME);
627 PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
628 PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME);
629 PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
630
631 #define SET(name, description) \
632 PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
633 #define FIRST_ERROR(name) \
634 PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name);
635 #include "unwind_stop_reasons.def"
636 #undef SET
637
638 Py_INCREF (&frame_object_type);
639 PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type);
640 }
641
642
643
644 static PyMethodDef frame_object_methods[] = {
645 { "is_valid", frapy_is_valid, METH_NOARGS,
646 "is_valid () -> Boolean.\n\
647 Return true if this frame is valid, false if not." },
648 { "name", frapy_name, METH_NOARGS,
649 "name () -> String.\n\
650 Return the function name of the frame, or None if it can't be determined." },
651 { "type", frapy_type, METH_NOARGS,
652 "type () -> Integer.\n\
653 Return the type of the frame." },
654 { "architecture", frapy_arch, METH_NOARGS,
655 "architecture () -> gdb.Architecture.\n\
656 Return the architecture of the frame." },
657 { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
658 "unwind_stop_reason () -> Integer.\n\
659 Return the reason why it's not possible to find frames older than this." },
660 { "pc", frapy_pc, METH_NOARGS,
661 "pc () -> Long.\n\
662 Return the frame's resume address." },
663 { "block", frapy_block, METH_NOARGS,
664 "block () -> gdb.Block.\n\
665 Return the frame's code block." },
666 { "function", frapy_function, METH_NOARGS,
667 "function () -> gdb.Symbol.\n\
668 Returns the symbol for the function corresponding to this frame." },
669 { "older", frapy_older, METH_NOARGS,
670 "older () -> gdb.Frame.\n\
671 Return the frame that called this frame." },
672 { "newer", frapy_newer, METH_NOARGS,
673 "newer () -> gdb.Frame.\n\
674 Return the frame called by this frame." },
675 { "find_sal", frapy_find_sal, METH_NOARGS,
676 "find_sal () -> gdb.Symtab_and_line.\n\
677 Return the frame's symtab and line." },
678 { "read_var", frapy_read_var, METH_VARARGS,
679 "read_var (variable) -> gdb.Value.\n\
680 Return the value of the variable in this frame." },
681 { "select", frapy_select, METH_NOARGS,
682 "Select this frame as the user's current frame." },
683 {NULL} /* Sentinel */
684 };
685
686 PyTypeObject frame_object_type = {
687 PyVarObject_HEAD_INIT (NULL, 0)
688 "gdb.Frame", /* tp_name */
689 sizeof (frame_object), /* tp_basicsize */
690 0, /* tp_itemsize */
691 0, /* tp_dealloc */
692 0, /* tp_print */
693 0, /* tp_getattr */
694 0, /* tp_setattr */
695 0, /* tp_compare */
696 0, /* tp_repr */
697 0, /* tp_as_number */
698 0, /* tp_as_sequence */
699 0, /* tp_as_mapping */
700 0, /* tp_hash */
701 0, /* tp_call */
702 frapy_str, /* tp_str */
703 0, /* tp_getattro */
704 0, /* tp_setattro */
705 0, /* tp_as_buffer */
706 Py_TPFLAGS_DEFAULT, /* tp_flags */
707 "GDB frame object", /* tp_doc */
708 0, /* tp_traverse */
709 0, /* tp_clear */
710 frapy_richcompare, /* tp_richcompare */
711 0, /* tp_weaklistoffset */
712 0, /* tp_iter */
713 0, /* tp_iternext */
714 frame_object_methods, /* tp_methods */
715 0, /* tp_members */
716 0, /* tp_getset */
717 0, /* tp_base */
718 0, /* tp_dict */
719 0, /* tp_descr_get */
720 0, /* tp_descr_set */
721 0, /* tp_dictoffset */
722 0, /* tp_init */
723 0, /* tp_alloc */
724 };
725