1 /* Python interface to stack frames 2 3 Copyright (C) 2008, 2009 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 30 typedef struct { 31 PyObject_HEAD 32 struct frame_id frame_id; 33 struct gdbarch *gdbarch; 34 35 /* Marks that the FRAME_ID member actually holds the ID of the frame next 36 to this, and not this frames' ID itself. This is a hack to permit Python 37 frame objects which represent invalid frames (i.e., the last frame_info 38 in a corrupt stack). The problem arises from the fact that this code 39 relies on FRAME_ID to uniquely identify a frame, which is not always true 40 for the last "frame" in a corrupt stack (it can have a null ID, or the same 41 ID as the previous frame). Whenever get_prev_frame returns NULL, we 42 record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */ 43 int frame_id_is_next; 44 } frame_object; 45 46 /* Require a valid frame. This must be called inside a TRY_CATCH, or 47 another context in which a gdb exception is allowed. */ 48 #define FRAPY_REQUIRE_VALID(frame_obj, frame) \ 49 do { \ 50 frame = frame_object_to_frame_info (frame_obj); \ 51 if (frame == NULL) \ 52 error ("Frame is invalid."); \ 53 } while (0) 54 55 static PyTypeObject frame_object_type; 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 static struct frame_info * 62 frame_object_to_frame_info (frame_object *frame_obj) 63 { 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 char *s; 83 PyObject *result; 84 struct ui_file *strfile; 85 86 strfile = mem_fileopen (); 87 fprint_frame_id (strfile, ((frame_object *) self)->frame_id); 88 s = ui_file_xstrdup (strfile, NULL); 89 result = PyString_FromString (s); 90 xfree (s); 91 92 return result; 93 } 94 95 /* Implementation of gdb.Frame.is_valid (self) -> Boolean. 96 Returns True if the frame corresponding to the frame_id of this 97 object still exists in the inferior. */ 98 99 static PyObject * 100 frapy_is_valid (PyObject *self, PyObject *args) 101 { 102 struct frame_info *frame; 103 104 frame = frame_object_to_frame_info ((frame_object *) self); 105 if (frame == NULL) 106 Py_RETURN_FALSE; 107 108 Py_RETURN_TRUE; 109 } 110 111 /* Implementation of gdb.Frame.name (self) -> String. 112 Returns the name of the function corresponding to this frame. */ 113 114 static PyObject * 115 frapy_name (PyObject *self, PyObject *args) 116 { 117 struct frame_info *frame; 118 char *name; 119 enum language lang; 120 PyObject *result; 121 volatile struct gdb_exception except; 122 123 TRY_CATCH (except, RETURN_MASK_ALL) 124 { 125 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 126 127 find_frame_funname (frame, &name, &lang); 128 } 129 GDB_PY_HANDLE_EXCEPTION (except); 130 131 if (name) 132 result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL); 133 else 134 { 135 result = Py_None; 136 Py_INCREF (Py_None); 137 } 138 139 return result; 140 } 141 142 /* Implementation of gdb.Frame.type (self) -> Integer. 143 Returns the frame type, namely one of the gdb.*_FRAME constants. */ 144 145 static PyObject * 146 frapy_type (PyObject *self, PyObject *args) 147 { 148 struct frame_info *frame; 149 enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */ 150 volatile struct gdb_exception except; 151 152 TRY_CATCH (except, RETURN_MASK_ALL) 153 { 154 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 155 156 type = get_frame_type (frame); 157 } 158 GDB_PY_HANDLE_EXCEPTION (except); 159 160 return PyInt_FromLong (type); 161 } 162 163 /* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer. 164 Returns one of the gdb.FRAME_UNWIND_* constants. */ 165 166 static PyObject * 167 frapy_unwind_stop_reason (PyObject *self, PyObject *args) 168 { 169 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */ 170 volatile struct gdb_exception except; 171 enum unwind_stop_reason stop_reason; 172 173 TRY_CATCH (except, RETURN_MASK_ALL) 174 { 175 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 176 } 177 GDB_PY_HANDLE_EXCEPTION (except); 178 179 stop_reason = get_frame_unwind_stop_reason (frame); 180 181 return PyInt_FromLong (stop_reason); 182 } 183 184 /* Implementation of gdb.Frame.pc (self) -> Long. 185 Returns the frame's resume address. */ 186 187 static PyObject * 188 frapy_pc (PyObject *self, PyObject *args) 189 { 190 CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */ 191 struct frame_info *frame; 192 volatile struct gdb_exception except; 193 194 TRY_CATCH (except, RETURN_MASK_ALL) 195 { 196 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 197 198 pc = get_frame_pc (frame); 199 } 200 GDB_PY_HANDLE_EXCEPTION (except); 201 202 return PyLong_FromUnsignedLongLong (pc); 203 } 204 205 /* Convert a frame_info struct to a Python Frame object. 206 Sets a Python exception and returns NULL on error. */ 207 208 static frame_object * 209 frame_info_to_frame_object (struct frame_info *frame) 210 { 211 frame_object *frame_obj; 212 213 frame_obj = PyObject_New (frame_object, &frame_object_type); 214 if (frame_obj == NULL) 215 { 216 PyErr_SetString (PyExc_MemoryError, "Could not allocate frame object."); 217 return NULL; 218 } 219 220 /* Try to get the previous frame, to determine if this is the last frame 221 in a corrupt stack. If so, we need to store the frame_id of the next 222 frame and not of this one (which is possibly invalid). */ 223 if (get_prev_frame (frame) == NULL 224 && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON 225 && get_next_frame (frame) != NULL) 226 { 227 frame_obj->frame_id = get_frame_id (get_next_frame (frame)); 228 frame_obj->frame_id_is_next = 1; 229 } 230 else 231 { 232 frame_obj->frame_id = get_frame_id (frame); 233 frame_obj->frame_id_is_next = 0; 234 } 235 236 frame_obj->gdbarch = get_frame_arch (frame); 237 238 return frame_obj; 239 } 240 241 /* Implementation of gdb.Frame.older (self) -> gdb.Frame. 242 Returns the frame immediately older (outer) to this frame, or None if 243 there isn't one. */ 244 245 static PyObject * 246 frapy_older (PyObject *self, PyObject *args) 247 { 248 struct frame_info *frame, *prev; 249 volatile struct gdb_exception except; 250 PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */ 251 252 TRY_CATCH (except, RETURN_MASK_ALL) 253 { 254 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 255 256 prev = get_prev_frame (frame); 257 if (prev) 258 prev_obj = (PyObject *) frame_info_to_frame_object (prev); 259 else 260 { 261 Py_INCREF (Py_None); 262 prev_obj = Py_None; 263 } 264 } 265 GDB_PY_HANDLE_EXCEPTION (except); 266 267 return prev_obj; 268 } 269 270 /* Implementation of gdb.Frame.newer (self) -> gdb.Frame. 271 Returns the frame immediately newer (inner) to this frame, or None if 272 there isn't one. */ 273 274 static PyObject * 275 frapy_newer (PyObject *self, PyObject *args) 276 { 277 struct frame_info *frame, *next; 278 volatile struct gdb_exception except; 279 PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */ 280 281 TRY_CATCH (except, RETURN_MASK_ALL) 282 { 283 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 284 285 next = get_next_frame (frame); 286 if (next) 287 next_obj = (PyObject *) frame_info_to_frame_object (next); 288 else 289 { 290 Py_INCREF (Py_None); 291 next_obj = Py_None; 292 } 293 } 294 GDB_PY_HANDLE_EXCEPTION (except); 295 296 return next_obj; 297 } 298 299 /* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value. 300 Returns the value of the given variable in this frame. The argument must be 301 a string. Returns None if GDB can't find the specified variable. */ 302 303 static PyObject * 304 frapy_read_var (PyObject *self, PyObject *args) 305 { 306 struct frame_info *frame; 307 PyObject *sym_obj; 308 struct symbol *var = NULL; /* gcc-4.3.2 false warning. */ 309 struct value *val = NULL; 310 volatile struct gdb_exception except; 311 312 if (!PyArg_ParseTuple (args, "O", &sym_obj)) 313 return NULL; 314 315 if (gdbpy_is_string (sym_obj)) 316 { 317 char *var_name; 318 struct block *block = NULL; 319 struct cleanup *cleanup; 320 volatile struct gdb_exception except; 321 322 var_name = python_string_to_target_string (sym_obj); 323 if (!var_name) 324 return NULL; 325 cleanup = make_cleanup (xfree, var_name); 326 327 TRY_CATCH (except, RETURN_MASK_ALL) 328 { 329 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 330 331 block = block_for_pc (get_frame_address_in_block (frame)); 332 var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL); 333 } 334 GDB_PY_HANDLE_EXCEPTION (except); 335 336 if (!var) 337 { 338 PyErr_Format (PyExc_ValueError, 339 _("variable '%s' not found"), var_name); 340 do_cleanups (cleanup); 341 342 return NULL; 343 } 344 345 do_cleanups (cleanup); 346 } 347 else 348 { 349 PyErr_SetString (PyExc_TypeError, 350 _("argument must be a symbol or string")); 351 return NULL; 352 } 353 354 TRY_CATCH (except, RETURN_MASK_ALL) 355 { 356 FRAPY_REQUIRE_VALID ((frame_object *) self, frame); 357 358 val = read_var_value (var, frame); 359 } 360 GDB_PY_HANDLE_EXCEPTION (except); 361 362 if (val) 363 return value_to_value_object (val); 364 365 Py_RETURN_NONE; 366 } 367 368 /* Implementation of gdb.selected_frame () -> gdb.Frame. 369 Returns the selected frame object. */ 370 371 PyObject * 372 gdbpy_selected_frame (PyObject *self, PyObject *args) 373 { 374 struct frame_info *frame; 375 frame_object *frame_obj = NULL; /* Initialize to appease gcc warning. */ 376 volatile struct gdb_exception except; 377 378 TRY_CATCH (except, RETURN_MASK_ALL) 379 { 380 frame = get_selected_frame ("No frame is currently selected."); 381 frame_obj = frame_info_to_frame_object (frame); 382 } 383 GDB_PY_HANDLE_EXCEPTION (except); 384 385 return (PyObject *) frame_obj; 386 } 387 388 /* Implementation of gdb.stop_reason_string (Integer) -> String. 389 Return a string explaining the unwind stop reason. */ 390 391 PyObject * 392 gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args) 393 { 394 int reason; 395 const char *str; 396 397 if (!PyArg_ParseTuple (args, "i", &reason)) 398 return NULL; 399 400 if (reason < 0 || reason > UNWIND_NO_SAVED_PC) 401 { 402 PyErr_SetString (PyExc_ValueError, "Invalid frame stop reason."); 403 return NULL; 404 } 405 406 str = frame_stop_reason_string (reason); 407 return PyUnicode_Decode (str, strlen (str), host_charset (), NULL); 408 } 409 410 /* Implements the equality comparison for Frame objects. 411 All other comparison operators will throw a TypeError Python exception, 412 as they aren't valid for frames. */ 413 414 static PyObject * 415 frapy_richcompare (PyObject *self, PyObject *other, int op) 416 { 417 int result; 418 419 if (!PyObject_TypeCheck (other, &frame_object_type) 420 || (op != Py_EQ && op != Py_NE)) 421 { 422 Py_INCREF (Py_NotImplemented); 423 return Py_NotImplemented; 424 } 425 426 if (frame_id_eq (((frame_object *) self)->frame_id, 427 ((frame_object *) other)->frame_id)) 428 result = Py_EQ; 429 else 430 result = Py_NE; 431 432 if (op == result) 433 Py_RETURN_TRUE; 434 Py_RETURN_FALSE; 435 } 436 437 /* Sets up the Frame API in the gdb module. */ 438 439 void 440 gdbpy_initialize_frames (void) 441 { 442 if (PyType_Ready (&frame_object_type) < 0) 443 return; 444 445 /* Note: These would probably be best exposed as class attributes of Frame, 446 but I don't know how to do it except by messing with the type's dictionary. 447 That seems too messy. */ 448 PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME); 449 PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME); 450 PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME); 451 PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME); 452 PyModule_AddIntConstant (gdb_module, 453 "FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON); 454 PyModule_AddIntConstant (gdb_module, 455 "FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID); 456 PyModule_AddIntConstant (gdb_module, 457 "FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR); 458 PyModule_AddIntConstant (gdb_module, 459 "FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID); 460 PyModule_AddIntConstant (gdb_module, 461 "FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID); 462 PyModule_AddIntConstant (gdb_module, 463 "FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC); 464 465 Py_INCREF (&frame_object_type); 466 PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type); 467 } 468 469 470 471 static PyMethodDef frame_object_methods[] = { 472 { "is_valid", frapy_is_valid, METH_NOARGS, 473 "is_valid () -> Boolean.\n\ 474 Return true if this frame is valid, false if not." }, 475 { "name", frapy_name, METH_NOARGS, 476 "name () -> String.\n\ 477 Return the function name of the frame, or None if it can't be determined." }, 478 { "type", frapy_type, METH_NOARGS, 479 "type () -> Integer.\n\ 480 Return the type of the frame." }, 481 { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS, 482 "unwind_stop_reason () -> Integer.\n\ 483 Return the reason why it's not possible to find frames older than this." }, 484 { "pc", frapy_pc, METH_NOARGS, 485 "pc () -> Long.\n\ 486 Return the frame's resume address." }, 487 { "older", frapy_older, METH_NOARGS, 488 "older () -> gdb.Frame.\n\ 489 Return the frame that called this frame." }, 490 { "newer", frapy_newer, METH_NOARGS, 491 "newer () -> gdb.Frame.\n\ 492 Return the frame called by this frame." }, 493 { "read_var", frapy_read_var, METH_VARARGS, 494 "read_var (variable) -> gdb.Value.\n\ 495 Return the value of the variable in this frame." }, 496 {NULL} /* Sentinel */ 497 }; 498 499 static PyTypeObject frame_object_type = { 500 PyObject_HEAD_INIT (NULL) 501 0, /* ob_size */ 502 "gdb.Frame", /* tp_name */ 503 sizeof (frame_object), /* tp_basicsize */ 504 0, /* tp_itemsize */ 505 0, /* tp_dealloc */ 506 0, /* tp_print */ 507 0, /* tp_getattr */ 508 0, /* tp_setattr */ 509 0, /* tp_compare */ 510 0, /* tp_repr */ 511 0, /* tp_as_number */ 512 0, /* tp_as_sequence */ 513 0, /* tp_as_mapping */ 514 0, /* tp_hash */ 515 0, /* tp_call */ 516 frapy_str, /* tp_str */ 517 0, /* tp_getattro */ 518 0, /* tp_setattro */ 519 0, /* tp_as_buffer */ 520 Py_TPFLAGS_DEFAULT, /* tp_flags */ 521 "GDB frame object", /* tp_doc */ 522 0, /* tp_traverse */ 523 0, /* tp_clear */ 524 frapy_richcompare, /* tp_richcompare */ 525 0, /* tp_weaklistoffset */ 526 0, /* tp_iter */ 527 0, /* tp_iternext */ 528 frame_object_methods, /* tp_methods */ 529 0, /* tp_members */ 530 0, /* tp_getset */ 531 0, /* tp_base */ 532 0, /* tp_dict */ 533 0, /* tp_descr_get */ 534 0, /* tp_descr_set */ 535 0, /* tp_dictoffset */ 536 0, /* tp_init */ 537 0, /* tp_alloc */ 538 PyType_GenericNew /* tp_new */ 539 }; 540