]> Git Repo - binutils.git/blob - gdb/python/py-frame.c
1d3152c75ddcf46253e689f5781805a50fe227a0
[binutils.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, NULL);
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 PyObject *
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 (PyObject *) 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   volatile struct gdb_exception except;
369   PyObject *sal_obj = NULL;   /* Initialize to appease gcc warning.  */
370
371   TRY_CATCH (except, RETURN_MASK_ALL)
372     {
373       FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
374
375       find_frame_sal (frame, &sal);
376       sal_obj = symtab_and_line_to_sal_object (sal);
377     }
378   GDB_PY_HANDLE_EXCEPTION (except);
379
380   return sal_obj;
381 }
382
383 /* Implementation of gdb.Frame.read_var_value (self, variable,
384    [block]) -> gdb.Value.  If the optional block argument is provided
385    start the search from that block, otherwise search from the frame's
386    current block (determined by examining the resume address of the
387    frame).  The variable argument must be a string or an instance of a
388    gdb.Symbol.  The block argument must be an instance of gdb.Block.  Returns
389    NULL on error, with a python exception set.  */
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   PyObject *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 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 };
This page took 0.052138 seconds and 2 git commands to generate.