OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [python/] [py-frame.c] - Blame information for rev 833

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* 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
 
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
 
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
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.