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