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