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
frame_object_to_frame_info(PyObject * obj)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 *
frapy_str(PyObject * self)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 *
frapy_repr(PyObject * self)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 *
frapy_is_valid(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_name(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_type(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_arch(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_unwind_stop_reason(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_pc(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_read_register(PyObject * self,PyObject * args,PyObject * kw)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_block(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frapy_function(PyObject * self,PyObject * args)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       GDB_PY_HANDLE_EXCEPTION (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 *
frame_info_to_frame_object(const frame_info_ptr & frame)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       gdbpy_convert_exception (except);
393       return NULL;
394     }
395 
396   return (PyObject *) frame_obj.release ();
397 }
398 
399 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
400    Returns the frame immediately older (outer) to this frame, or None if
401    there isn't one.  */
402 
403 static PyObject *
frapy_older(PyObject * self,PyObject * args)404 frapy_older (PyObject *self, PyObject *args)
405 {
406   frame_info_ptr frame, prev = NULL;
407   PyObject *prev_obj = NULL;   /* Initialize to appease gcc warning.  */
408 
409   try
410     {
411       FRAPY_REQUIRE_VALID (self, frame);
412 
413       prev = get_prev_frame (frame);
414     }
415   catch (const gdb_exception &except)
416     {
417       GDB_PY_HANDLE_EXCEPTION (except);
418     }
419 
420   if (prev)
421     prev_obj = 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 
435 static PyObject *
frapy_newer(PyObject * self,PyObject * args)436 frapy_newer (PyObject *self, PyObject *args)
437 {
438   frame_info_ptr 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 (const gdb_exception &except)
448     {
449       GDB_PY_HANDLE_EXCEPTION (except);
450     }
451 
452   if (next)
453     next_obj = frame_info_to_frame_object (next);
454   else
455     {
456       Py_INCREF (Py_None);
457       next_obj = Py_None;
458     }
459 
460   return next_obj;
461 }
462 
463 /* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
464    Returns the frame's symtab and line.  */
465 
466 static PyObject *
frapy_find_sal(PyObject * self,PyObject * args)467 frapy_find_sal (PyObject *self, PyObject *args)
468 {
469   frame_info_ptr frame;
470   PyObject *sal_obj = NULL;   /* Initialize to appease gcc warning.  */
471 
472   try
473     {
474       FRAPY_REQUIRE_VALID (self, frame);
475 
476       symtab_and_line sal = find_frame_sal (frame);
477       sal_obj = symtab_and_line_to_sal_object (sal);
478     }
479   catch (const gdb_exception &except)
480     {
481       GDB_PY_HANDLE_EXCEPTION (except);
482     }
483 
484   return sal_obj;
485 }
486 
487 /* Implementation of gdb.Frame.read_var_value (self, variable,
488    [block]) -> gdb.Value.  If the optional block argument is provided
489    start the search from that block, otherwise search from the frame's
490    current block (determined by examining the resume address of the
491    frame).  The variable argument must be a string or an instance of a
492    gdb.Symbol.  The block argument must be an instance of gdb.Block.  Returns
493    NULL on error, with a python exception set.  */
494 static PyObject *
frapy_read_var(PyObject * self,PyObject * args,PyObject * kw)495 frapy_read_var (PyObject *self, PyObject *args, PyObject *kw)
496 {
497   frame_info_ptr frame;
498   PyObject *sym_obj, *block_obj = NULL;
499   struct symbol *var = NULL;  /* gcc-4.3.2 false warning.  */
500   const struct block *block = NULL;
501 
502   static const char *keywords[] = { "variable", "block", nullptr };
503   if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|O!", keywords,
504                                                   &sym_obj, &block_object_type,
505                                                   &block_obj))
506     return nullptr;
507 
508   if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
509     var = symbol_object_to_symbol (sym_obj);
510   else if (gdbpy_is_string (sym_obj))
511     {
512       gdb::unique_xmalloc_ptr<char>
513           var_name (python_string_to_target_string (sym_obj));
514 
515       if (!var_name)
516           return NULL;
517 
518       if (block_obj != nullptr)
519           {
520             /* This call should only fail if the type of BLOCK_OBJ is wrong,
521                and we ensure the type is correct when we parse the arguments,
522                so we can just assert the return value is not nullptr.  */
523             block = block_object_to_block (block_obj);
524             gdb_assert (block != nullptr);
525           }
526 
527       try
528           {
529             struct block_symbol lookup_sym;
530             FRAPY_REQUIRE_VALID (self, frame);
531 
532             if (!block)
533               block = get_frame_block (frame, NULL);
534             lookup_sym = lookup_symbol (var_name.get (), block,
535                                               SEARCH_VFT, nullptr);
536             var = lookup_sym.symbol;
537             block = lookup_sym.block;
538           }
539       catch (const gdb_exception &except)
540           {
541             gdbpy_convert_exception (except);
542             return NULL;
543           }
544 
545       if (!var)
546           {
547             PyErr_Format (PyExc_ValueError,
548                               _("Variable '%s' not found."), var_name.get ());
549 
550             return NULL;
551           }
552     }
553   else
554     {
555       PyErr_Format (PyExc_TypeError,
556                         _("argument 1 must be gdb.Symbol or str, not %s"),
557                         Py_TYPE (sym_obj)->tp_name);
558       return NULL;
559     }
560 
561   PyObject *result = nullptr;
562   try
563     {
564       FRAPY_REQUIRE_VALID (self, frame);
565 
566       scoped_value_mark free_values;
567       struct value *val = read_var_value (var, block, frame);
568       result = value_to_value_object (val);
569     }
570   catch (const gdb_exception &except)
571     {
572       GDB_PY_HANDLE_EXCEPTION (except);
573     }
574 
575   return result;
576 }
577 
578 /* Select this frame.  */
579 
580 static PyObject *
frapy_select(PyObject * self,PyObject * args)581 frapy_select (PyObject *self, PyObject *args)
582 {
583   frame_info_ptr fi;
584 
585   try
586     {
587       FRAPY_REQUIRE_VALID (self, fi);
588 
589       select_frame (fi);
590     }
591   catch (const gdb_exception &except)
592     {
593       GDB_PY_HANDLE_EXCEPTION (except);
594     }
595 
596   Py_RETURN_NONE;
597 }
598 
599 /* The stack frame level for this frame.  */
600 
601 static PyObject *
frapy_level(PyObject * self,PyObject * args)602 frapy_level (PyObject *self, PyObject *args)
603 {
604   frame_info_ptr fi;
605 
606   try
607     {
608       FRAPY_REQUIRE_VALID (self, fi);
609 
610       return gdb_py_object_from_longest (frame_relative_level (fi)).release ();
611     }
612   catch (const gdb_exception &except)
613     {
614       GDB_PY_HANDLE_EXCEPTION (except);
615     }
616 
617   Py_RETURN_NONE;
618 }
619 
620 /* The language for this frame.  */
621 
622 static PyObject *
frapy_language(PyObject * self,PyObject * args)623 frapy_language (PyObject *self, PyObject *args)
624 {
625   try
626     {
627       frame_info_ptr fi;
628       FRAPY_REQUIRE_VALID (self, fi);
629 
630       enum language lang = get_frame_language (fi);
631       const language_defn *lang_def = language_def (lang);
632 
633       return host_string_to_python_string (lang_def->name ()).release ();
634     }
635   catch (const gdb_exception &except)
636     {
637       GDB_PY_HANDLE_EXCEPTION (except);
638     }
639 
640   Py_RETURN_NONE;
641 }
642 
643 /* The static link for this frame.  */
644 
645 static PyObject *
frapy_static_link(PyObject * self,PyObject * args)646 frapy_static_link (PyObject *self, PyObject *args)
647 {
648   frame_info_ptr link;
649 
650   try
651     {
652       FRAPY_REQUIRE_VALID (self, link);
653 
654       link = frame_follow_static_link (link);
655     }
656   catch (const gdb_exception &except)
657     {
658       GDB_PY_HANDLE_EXCEPTION (except);
659     }
660 
661   if (link == nullptr)
662     Py_RETURN_NONE;
663 
664   return frame_info_to_frame_object (link);
665 }
666 
667 /* Implementation of gdb.newest_frame () -> gdb.Frame.
668    Returns the newest frame object.  */
669 
670 PyObject *
gdbpy_newest_frame(PyObject * self,PyObject * args)671 gdbpy_newest_frame (PyObject *self, PyObject *args)
672 {
673   frame_info_ptr frame = NULL;
674 
675   try
676     {
677       frame = get_current_frame ();
678     }
679   catch (const gdb_exception &except)
680     {
681       GDB_PY_HANDLE_EXCEPTION (except);
682     }
683 
684   return frame_info_to_frame_object (frame);
685 }
686 
687 /* Implementation of gdb.selected_frame () -> gdb.Frame.
688    Returns the selected frame object.  */
689 
690 PyObject *
gdbpy_selected_frame(PyObject * self,PyObject * args)691 gdbpy_selected_frame (PyObject *self, PyObject *args)
692 {
693   frame_info_ptr frame = NULL;
694 
695   try
696     {
697       frame = get_selected_frame ("No frame is currently selected.");
698     }
699   catch (const gdb_exception &except)
700     {
701       GDB_PY_HANDLE_EXCEPTION (except);
702     }
703 
704   return frame_info_to_frame_object (frame);
705 }
706 
707 /* Implementation of gdb.stop_reason_string (Integer) -> String.
708    Return a string explaining the unwind stop reason.  */
709 
710 PyObject *
gdbpy_frame_stop_reason_string(PyObject * self,PyObject * args)711 gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
712 {
713   int reason;
714   const char *str;
715 
716   if (!PyArg_ParseTuple (args, "i", &reason))
717     return NULL;
718 
719   if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
720     {
721       PyErr_SetString (PyExc_ValueError,
722                            _("Invalid frame stop reason."));
723       return NULL;
724     }
725 
726   str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
727   return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
728 }
729 
730 /* Implements the equality comparison for Frame objects.
731    All other comparison operators will throw a TypeError Python exception,
732    as they aren't valid for frames.  */
733 
734 static PyObject *
frapy_richcompare(PyObject * self,PyObject * other,int op)735 frapy_richcompare (PyObject *self, PyObject *other, int op)
736 {
737   int result;
738 
739   if (!PyObject_TypeCheck (other, &frame_object_type)
740       || (op != Py_EQ && op != Py_NE))
741     {
742       Py_INCREF (Py_NotImplemented);
743       return Py_NotImplemented;
744     }
745 
746   frame_object *self_frame = (frame_object *) self;
747   frame_object *other_frame = (frame_object *) other;
748 
749   if (self_frame->frame_id_is_next == other_frame->frame_id_is_next
750       && self_frame->frame_id == other_frame->frame_id)
751     result = Py_EQ;
752   else
753     result = Py_NE;
754 
755   if (op == result)
756     Py_RETURN_TRUE;
757   Py_RETURN_FALSE;
758 }
759 
760 /* Sets up the Frame API in the gdb module.  */
761 
762 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_frames(void)763 gdbpy_initialize_frames (void)
764 {
765   frame_object_type.tp_new = PyType_GenericNew;
766   if (PyType_Ready (&frame_object_type) < 0)
767     return -1;
768 
769   /* Note: These would probably be best exposed as class attributes of
770      Frame, but I don't know how to do it except by messing with the
771      type's dictionary.  That seems too messy.  */
772   if (PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME) < 0
773       || PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME) < 0
774       || PyModule_AddIntConstant (gdb_module, "INLINE_FRAME", INLINE_FRAME) < 0
775       || PyModule_AddIntConstant (gdb_module, "TAILCALL_FRAME",
776                                           TAILCALL_FRAME) < 0
777       || PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME",
778                                           SIGTRAMP_FRAME) < 0
779       || PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME) < 0
780       || PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME",
781                                           SENTINEL_FRAME) < 0)
782     return -1;
783 
784 #define SET(name, description) \
785   if (PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name) < 0) \
786     return -1;
787 #include "unwind_stop_reasons.def"
788 #undef SET
789 
790   return gdb_pymodule_addobject (gdb_module, "Frame",
791                                          (PyObject *) &frame_object_type);
792 }
793 
794 GDBPY_INITIALIZE_FILE (gdbpy_initialize_frames);
795 
796 
797 
798 static PyMethodDef frame_object_methods[] = {
799   { "is_valid", frapy_is_valid, METH_NOARGS,
800     "is_valid () -> Boolean.\n\
801 Return true if this frame is valid, false if not." },
802   { "name", frapy_name, METH_NOARGS,
803     "name () -> String.\n\
804 Return the function name of the frame, or None if it can't be determined." },
805   { "type", frapy_type, METH_NOARGS,
806     "type () -> Integer.\n\
807 Return the type of the frame." },
808   { "architecture", frapy_arch, METH_NOARGS,
809     "architecture () -> gdb.Architecture.\n\
810 Return the architecture of the frame." },
811   { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
812     "unwind_stop_reason () -> Integer.\n\
813 Return the reason why it's not possible to find frames older than this." },
814   { "pc", frapy_pc, METH_NOARGS,
815     "pc () -> Long.\n\
816 Return the frame's resume address." },
817   { "read_register", (PyCFunction) frapy_read_register,
818     METH_VARARGS | METH_KEYWORDS,
819     "read_register (register_name) -> gdb.Value\n\
820 Return the value of the register in the frame." },
821   { "block", frapy_block, METH_NOARGS,
822     "block () -> gdb.Block.\n\
823 Return the frame's code block." },
824   { "function", frapy_function, METH_NOARGS,
825     "function () -> gdb.Symbol.\n\
826 Returns the symbol for the function corresponding to this frame." },
827   { "older", frapy_older, METH_NOARGS,
828     "older () -> gdb.Frame.\n\
829 Return the frame that called this frame." },
830   { "newer", frapy_newer, METH_NOARGS,
831     "newer () -> gdb.Frame.\n\
832 Return the frame called by this frame." },
833   { "find_sal", frapy_find_sal, METH_NOARGS,
834     "find_sal () -> gdb.Symtab_and_line.\n\
835 Return the frame's symtab and line." },
836   { "read_var", (PyCFunction) frapy_read_var, METH_VARARGS | METH_KEYWORDS,
837     "read_var (variable) -> gdb.Value.\n\
838 Return the value of the variable in this frame." },
839   { "select", frapy_select, METH_NOARGS,
840     "Select this frame as the user's current frame." },
841   { "level", frapy_level, METH_NOARGS,
842     "The stack level of this frame." },
843   { "language", frapy_language, METH_NOARGS,
844     "The language of this frame." },
845   { "static_link", frapy_static_link, METH_NOARGS,
846     "The static link of this frame, or None." },
847   {NULL}  /* Sentinel */
848 };
849 
850 PyTypeObject frame_object_type = {
851   PyVarObject_HEAD_INIT (NULL, 0)
852   "gdb.Frame",                            /* tp_name */
853   sizeof (frame_object),        /* tp_basicsize */
854   0,                                      /* tp_itemsize */
855   0,                                      /* tp_dealloc */
856   0,                                      /* tp_print */
857   0,                                      /* tp_getattr */
858   0,                                      /* tp_setattr */
859   0,                                      /* tp_compare */
860   frapy_repr,                             /* tp_repr */
861   0,                                      /* tp_as_number */
862   0,                                      /* tp_as_sequence */
863   0,                                      /* tp_as_mapping */
864   0,                                      /* tp_hash  */
865   0,                                      /* tp_call */
866   frapy_str,                              /* tp_str */
867   0,                                      /* tp_getattro */
868   0,                                      /* tp_setattro */
869   0,                                      /* tp_as_buffer */
870   Py_TPFLAGS_DEFAULT,                     /* tp_flags */
871   "GDB frame object",                     /* tp_doc */
872   0,                                      /* tp_traverse */
873   0,                                      /* tp_clear */
874   frapy_richcompare,                      /* tp_richcompare */
875   0,                                      /* tp_weaklistoffset */
876   0,                                      /* tp_iter */
877   0,                                      /* tp_iternext */
878   frame_object_methods,                   /* tp_methods */
879   0,                                      /* tp_members */
880   0,                                      /* tp_getset */
881   0,                                      /* tp_base */
882   0,                                      /* tp_dict */
883   0,                                      /* tp_descr_get */
884   0,                                      /* tp_descr_set */
885   0,                                      /* tp_dictoffset */
886   0,                                      /* tp_init */
887   0,                                      /* tp_alloc */
888 };
889