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