2009-11-13 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / 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 };
This page took 0.041196 seconds and 4 git commands to generate.