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