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