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