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