Import gdb-7.0
[dragonfly.git] / contrib / gdb-7 / gdb / python / py-frame.c
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 \f
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 };