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