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