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