Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Thiago Jung Bauermann <bauerman@br.ibm.com>
To: gdb-patches@sourceware.org
Subject: [RFC][patch 6/9] export frames to Python
Date: Tue, 29 Apr 2008 15:59:00 -0000	[thread overview]
Message-ID: <20080429155305.189018566@br.ibm.com> (raw)
In-Reply-To: <20080429155212.444237503@br.ibm.com>

[-- Attachment #1: python-frames.diff --]
[-- Type: text/plain, Size: 26227 bytes --]

2008-04-29  Thiago Jung Bauermann  <bauerman@br.ibm.com>
	    Tom Tromey <tromey@redhat.com>

	* Makefile.in (SUBDIR_PYTHON_OBS): Add python-frame.o.
	(SUBDIR_PYTHON_SRCS): Add python/frame.c.
	(python.o): Depend on solib.h.
	(python-frame.o): New target.
	* python/frame.c: New file.
	* python/python-internal.h (gdbpy_get_frames,
	gdbpy_get_current_frame, gdbpy_frame_stop_reason_string,
	gdbpy_get_selected_frame, gdbpy_initialize_frames): Declare.
	* python/python.c (demand_python): Add frame functions.  Call
	gdbpy_initialize_frames.
	(gdbpy_solib_address): New function.
	Include solib.h
	* stack.c (print_frame): Factor out code to find function name
	and language into ...
	(find_frame_funname): ... this new function.
	* stack.h (find_frame_funname): Declare.

Index: tromey.git/gdb/Makefile.in
===================================================================
--- tromey.git.orig/gdb/Makefile.in	2008-04-29 11:05:20.000000000 -0300
+++ tromey.git/gdb/Makefile.in	2008-04-29 11:05:45.000000000 -0300
@@ -264,12 +264,14 @@ SUBDIR_PYTHON_OBS = \
 	python.o \
 	python-breakpoint.o \
 	python-cmd.o \
+	python-frame.o \
 	python-hooks.o \
 	python-value.o
 SUBDIR_PYTHON_SRCS = \
 	python/python.c \
 	python/breakpoint.c \
 	python/cmd.c \
+	python/frame.c \
 	python/hooks.c \
 	python/value.c
 SUBDIR_PYTHON_DEPS =
@@ -3417,7 +3419,7 @@ PYTHON_CFLAGS=-fno-strict-aliasing
 
 python.o: $(srcdir)/python/python.c $(defs_h) $(python_h) \
 	$(command_h) $(libiberty_h) $(cli_decode_h) $(charset_h) $(top_h) \
-	$(exceptions_h) $(python_internal_h) $(version_h)
+	$(exceptions_h) $(python_internal_h) $(version_h) $(solib_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
 python-breakpoint.o: $(srcdir)/python/breakpoint.c $(defs_h) $(python_h) \
 	$(value_h) $(exceptions_h) $(python_internal_h) $(charset_h) \
@@ -3429,6 +3431,11 @@ python-cmd.o: $(srcdir)/python/cmd.c $(d
 	$(gdbcmd_h) $(cli_decode_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \
 	$(srcdir)/python/cmd.c -o python-cmd.o
+python-frame.o: $(srcdir)/python/frame.c $(defs_h)  $(python_h) \
+	$(python_internal_h) $(frame_h) $(exceptions_h) $(symtab_h) \
+	$(charset_h) $(stack_h) $(value_h)
+	$(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \
+	$(srcdir)/python/frame.c -o python-frame.o
 python-hooks.o: $(srcdir)/python/hooks.c $(defs_h) $(cli_decode_h) \
 	$(charset_h) $(gdb_events_h) $(python_h) $(python_internal_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \
Index: tromey.git/gdb/python/frame.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ tromey.git/gdb/python/frame.c	2008-04-29 11:05:54.000000000 -0300
@@ -0,0 +1,536 @@
+/* Python interface to stack frames
+
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "charset.h"
+#include "frame.h"
+#include "exceptions.h"
+#include "symtab.h"
+#include "stack.h"
+#include "value.h"
+#include "python-internal.h"
+
+typedef struct {
+  PyObject_HEAD
+  struct frame_id frame_id;
+  struct gdbarch *gdbarch;
+
+  /* Marks that the FRAME_ID member actually holds the ID of the frame next
+     to this, and not this frames' ID itself.  This is a hack to permit Python
+     frame objects which represent invalid frames (i.e., the last frame_info
+     in a corrupt stack).  The problem arises from the fact that this code
+     relies on FRAME_ID to uniquely identify a frame, which is not always true
+     for the last "frame" in a corrupt stack (it can have a null ID, or the same
+     ID as the  previous frame).  Whenever get_prev_frame returns NULL, we
+     record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1.  */
+  int frame_id_is_next;
+} frame_object;
+
+static frame_object *frame_info_to_frame_object (struct frame_info *frame);
+static struct frame_info *frame_object_to_frame_info (frame_object *frame_obj);
+
+static PyObject *frapy_str (PyObject *self);
+static PyObject *frapy_equal_p (PyObject *self, PyObject *args);
+static PyObject *frapy_inner_p (PyObject *self, PyObject *args);
+static PyObject *frapy_is_valid (PyObject *self, PyObject *args);
+static PyObject *frapy_get_name (PyObject *self, PyObject *args);
+static PyObject *frapy_get_type (PyObject *self, PyObject *args);
+static PyObject *frapy_get_unwind_stop_reason (PyObject *self, PyObject *args);
+static PyObject *frapy_get_pc (PyObject *self, PyObject *args);
+static PyObject *frapy_get_address_in_block (PyObject *self, PyObject *args);
+static PyObject *frapy_get_prev (PyObject *self, PyObject *args);
+static PyObject *frapy_get_next (PyObject *self, PyObject *args);
+
+#define FRAPY_REQUIRE_VALID(frame_obj, frame)			      \
+    do {							      \
+      frame = frame_object_to_frame_info (frame_obj);		      \
+      if (frame == NULL)					      \
+        {							      \
+	  PyErr_SetString (PyExc_RuntimeError, "Frame is invalid.");  \
+	  return NULL;						      \
+	}							      \
+    } while (0)
+
+static PyMethodDef frame_object_methods[] = {
+  { "equals", frapy_equal_p, METH_VARARGS, "Compare frames." },
+  { "is_inner_than", frapy_inner_p, METH_VARARGS,
+    "Return true if this frame is strictly inner than the other frame." },
+  { "is_valid", frapy_is_valid, METH_NOARGS,
+    "Return true if this frame is valid, false if not." },
+  { "get_name", frapy_get_name, METH_NOARGS,
+    "Return the function name of the frame." },
+  { "get_type", frapy_get_type, METH_NOARGS, "Return the type of the frame." },
+  { "get_unwind_stop_reason", frapy_get_unwind_stop_reason,
+    METH_NOARGS, "Return the function name of the frame." },
+  { "get_pc", frapy_get_pc, METH_NOARGS, "Return the frame's resume address." },
+  { "get_address_in_block", frapy_get_address_in_block, METH_NOARGS,
+    "Return an address which falls within the frame's code block." },
+  { "get_prev", frapy_get_prev, METH_NOARGS,
+    "Return the previous (outer) frame." },
+  { "get_next", frapy_get_next, METH_NOARGS, "Return the next (inner) frame." },
+  {NULL}  /* Sentinel */
+};
+
+static PyTypeObject frame_object_type = {
+  PyObject_HEAD_INIT (NULL)
+  0,				  /*ob_size*/
+  "gdb.Frame",			  /*tp_name*/
+  sizeof (frame_object),	  /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  0,				  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  frapy_str,			  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro*/
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  "GDB frame object",		  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  frame_object_methods		  /* tp_methods */
+};
+
+
+static PyObject *
+frapy_str (PyObject *self)
+{
+  char *s;
+  long len;
+  PyObject *result;
+  struct ui_file *strfile;
+
+  strfile = mem_fileopen ();
+  fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
+  s = ui_file_xstrdup (strfile, &len);
+  result = PyString_FromString (s);
+  xfree (s);
+
+  return result;
+}
+
+static PyObject *
+frapy_is_valid (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+
+  frame = frame_object_to_frame_info ((frame_object *) self);
+  if (frame == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
+static PyObject *
+frapy_equal_p (PyObject *self, PyObject *args)
+{
+  int equalp = 0;	  /* Initialize to appease gcc warning.  */
+  frame_object *self_frame = (frame_object *) self;
+  frame_object *other;
+  volatile struct gdb_exception except;
+
+  if (!PyArg_ParseTuple (args, "O!", &frame_object_type, &other))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      equalp = frame_id_eq (self_frame->frame_id, other->frame_id);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (equalp)
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+static PyObject *
+frapy_inner_p (PyObject *self, PyObject *args)
+{
+  int innerp = 0;	  /* Initialize to appease gcc warning.  */
+  frame_object *self_frame = (frame_object *) self;
+  frame_object *other;
+  volatile struct gdb_exception except;
+
+  if (!PyArg_ParseTuple (args, "O!", &frame_object_type, &other))
+    return NULL;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      /* It doesn't make sense to compare frames from different arches.  */
+      if (self_frame->gdbarch != other->gdbarch)
+	{
+	  PyErr_SetString (PyExc_ValueError,
+			   "Frames are from different architectures.");
+	  return NULL;
+	}
+
+      innerp = frame_id_inner (self_frame->gdbarch,
+			       self_frame->frame_id, other->frame_id);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (innerp)
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
+static PyObject *
+frapy_get_name (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+  char *name;
+  enum language lang;
+  PyObject *result;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      find_frame_funname (frame, &name, &lang);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  if (name)
+    result = PyString_Decode (name, strlen (name), host_charset (),
+			      NULL /* FIXME */);
+  else
+    {
+      result = Py_None;
+      Py_INCREF (Py_None);
+    }
+
+  return result;
+}
+
+static PyObject *
+frapy_get_type (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+  enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning.  */
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      type = get_frame_type (frame);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return PyInt_FromLong (type);
+}
+
+static PyObject *
+frapy_get_unwind_stop_reason (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame = NULL;    /* Initialize to appease gcc warning.  */
+  volatile struct gdb_exception except;
+  enum unwind_stop_reason stop_reason;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  stop_reason = get_frame_unwind_stop_reason (frame);
+
+  return PyInt_FromLong (stop_reason);
+}
+
+static PyObject *
+frapy_get_pc (PyObject *self, PyObject *args)
+{
+  CORE_ADDR pc = 0;	      /* Initialize to appease gcc warning.  */
+  struct frame_info *frame;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      pc = get_frame_pc (frame);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return PyLong_FromUnsignedLongLong (pc);
+}
+
+static PyObject *
+frapy_get_address_in_block (PyObject *self, PyObject *args)
+{
+  CORE_ADDR pc = 0;	      /* Initialize to appease gcc warning.  */
+  struct frame_info *frame;
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      pc = get_frame_address_in_block (frame);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return PyLong_FromUnsignedLongLong (pc);
+}
+
+static frame_object *
+frame_info_to_frame_object (struct frame_info *frame)
+{
+  frame_object *frame_obj;
+
+  frame_obj = PyObject_New (frame_object, &frame_object_type);
+  if (frame_obj == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError, "Could not allocate frame object.");
+      return NULL;
+    }
+
+  /* Try to get the previous frame, to determine if this is the last frame
+     in a corrupt stack.  If so, we need to store the frame_id of the next
+     frame and not of this one (which is possibly invalid).  */
+  if (get_prev_frame (frame) == NULL
+      && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
+      && get_next_frame (frame) != NULL)
+    {
+      frame_obj->frame_id = get_frame_id (get_next_frame (frame));
+      frame_obj->frame_id_is_next = 1;
+    }
+  else
+    {
+      frame_obj->frame_id = get_frame_id (frame);
+      frame_obj->frame_id_is_next = 0;
+    }
+
+  frame_obj->gdbarch = get_frame_arch (frame);
+
+  return frame_obj;
+}
+
+static struct frame_info *
+frame_object_to_frame_info (frame_object *frame_obj)
+{
+  struct frame_info *frame;
+
+  frame = frame_find_by_id (frame_obj->frame_id);
+  if (frame == NULL)
+    return NULL;
+
+  if (frame_obj->frame_id_is_next)
+    frame = get_prev_frame (frame);
+
+  return frame;
+}
+
+static PyObject *
+frapy_get_prev (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame, *prev;
+  volatile struct gdb_exception except;
+  PyObject *prev_obj = NULL;   /* Initialize to appease gcc warning.  */
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      prev = get_prev_frame (frame);
+      if (prev)
+	prev_obj = (PyObject *) frame_info_to_frame_object (prev);
+      else
+	{
+	  Py_INCREF (Py_None);
+	  prev_obj = Py_None;
+	}
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return prev_obj;
+}
+
+static PyObject *
+frapy_get_next (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame, *next;
+  volatile struct gdb_exception except;
+  PyObject *next_obj = NULL;   /* Initialize to appease gcc warning.  */
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+      next = get_next_frame (frame);
+      if (next)
+	next_obj = (PyObject *) frame_info_to_frame_object (next);
+      else
+	{
+	  Py_INCREF (Py_None);
+	  next_obj = Py_None;
+	}
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return next_obj;
+}
+
+PyObject *
+gdbpy_get_frames (PyObject *self, PyObject *args)
+{
+  int result = 0;
+  struct frame_info *frame;
+  frame_object *frame_obj;
+  PyObject *list, *tuple;
+  volatile struct gdb_exception except;
+
+  list = PyList_New (0);
+  if (list == NULL)
+    {
+      PyErr_SetString (PyExc_MemoryError, "Could not allocate frames list.");
+      return NULL;
+    }
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      for (frame = get_current_frame (); frame; frame = get_prev_frame (frame))
+	{
+	  frame_obj = frame_info_to_frame_object (frame);
+	  if (frame_obj == NULL)
+	    {
+	      Py_DECREF (list);
+	      return NULL;
+	    }
+
+	  PyList_Append (list, (PyObject *) frame_obj);
+	}
+    }
+  if (except.reason < 0)
+    {
+      Py_DECREF (list);
+      return PyErr_Format (except.reason == RETURN_QUIT
+			   ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+			   "%s", except.message);
+    }
+
+  tuple = PyList_AsTuple (list);
+  Py_DECREF (list);
+
+  return tuple;
+}
+
+PyObject *
+gdbpy_get_current_frame (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+  frame_object *frame_obj = NULL;   /* Initialize to appease gcc warning.  */
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      frame = get_current_frame ();
+      frame_obj = frame_info_to_frame_object (frame);
+      if (frame_obj == NULL)
+	return NULL;
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return (PyObject *) frame_obj;
+}
+
+PyObject *
+gdbpy_get_selected_frame (PyObject *self, PyObject *args)
+{
+  struct frame_info *frame;
+  frame_object *frame_obj = NULL;   /* Initialize to appease gcc warning.  */
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      frame = get_selected_frame ("No frame is currently selected.");
+      frame_obj = frame_info_to_frame_object (frame);
+      if (frame_obj == NULL)
+	return NULL;
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
+  return (PyObject *) frame_obj;
+}
+
+PyObject *
+gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
+{
+  int reason;
+  const char *str;
+
+  if (!PyArg_ParseTuple (args, "i", &reason))
+    return NULL;
+
+  if (reason < 0 || reason > UNWIND_NO_SAVED_PC)
+    {
+      PyErr_SetString (PyExc_ValueError, "Invalid frame stop reason.");
+      return NULL;
+    }
+
+  str = frame_stop_reason_string (reason);
+  return PyString_Decode (str, strlen (str), host_charset (), NULL /* FIXME */);
+}
+
+void
+gdbpy_initialize_frames (void)
+{
+  frame_object_type.tp_new = PyType_GenericNew;
+  if (PyType_Ready (&frame_object_type) < 0)
+    return;
+
+  /* FIXME: These would probably be best exposed as class attributes of Frame,
+     but I don't know how to do it except by messing with the type's dictionary.
+     That seems too messy.  */
+  PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME);
+  PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME);
+  PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME);
+  PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME);
+  PyModule_AddIntConstant (gdb_module,
+			   "FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON);
+  PyModule_AddIntConstant (gdb_module,
+			   "FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID);
+  PyModule_AddIntConstant (gdb_module,
+			   "FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR);
+  PyModule_AddIntConstant (gdb_module,
+			   "FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID);
+  PyModule_AddIntConstant (gdb_module,
+			   "FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID);
+  PyModule_AddIntConstant (gdb_module,
+			   "FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC);
+
+  Py_INCREF (&frame_object_type);
+  PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type);
+}
Index: tromey.git/gdb/python/python-internal.h
===================================================================
--- tromey.git.orig/gdb/python/python-internal.h	2008-04-29 11:05:20.000000000 -0300
+++ tromey.git/gdb/python/python-internal.h	2008-04-29 11:05:45.000000000 -0300
@@ -32,6 +32,10 @@ extern PyTypeObject value_object_type;
 PyObject *gdbpy_make_value_from_int (PyObject *self, PyObject *args);
 PyObject *gdbpy_get_value_from_history (PyObject *self, PyObject *args);
 PyObject *gdbpy_get_breakpoints (PyObject *, PyObject *);
+PyObject *gdbpy_get_frames (PyObject *, PyObject *);
+PyObject *gdbpy_get_current_frame (PyObject *, PyObject *);
+PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
+PyObject *gdbpy_get_selected_frame (PyObject *self, PyObject *args);
 
 PyObject *variable_to_python (struct cmd_list_element *);
 PyObject *value_to_value_object (struct value *v);
@@ -44,6 +48,7 @@ PyObject *gdbpy_get_hook_function (const
 void gdbpy_initialize_values (void);
 void gdbpy_initialize_hooks (void);
 void gdbpy_initialize_breakpoints (void);
+void gdbpy_initialize_frames (void);
 void gdbpy_initialize_commands (void);
 
 /* Use this after a TRY_EXCEPT to throw the appropriate Python
Index: tromey.git/gdb/python/python.c
===================================================================
--- tromey.git.orig/gdb/python/python.c	2008-04-29 11:05:20.000000000 -0300
+++ tromey.git/gdb/python/python.c	2008-04-29 11:05:45.000000000 -0300
@@ -24,6 +24,7 @@
 #include "cli/cli-decode.h"
 #include "charset.h"
 #include "top.h"
+#include "solib.h"
 #include "exceptions.h"
 #include "python-internal.h"
 #include "version.h"
@@ -34,6 +35,7 @@ PyObject *gdb_module;
 
 static PyObject *get_show_variable (PyObject *, PyObject *);
 static PyObject *execute_gdb_command (PyObject *, PyObject *);
+static PyObject *gdbpy_solib_address (PyObject *, PyObject *);
 
 
 void
@@ -56,6 +58,18 @@ demand_python ()
 	{ "get_breakpoints", gdbpy_get_breakpoints, METH_NOARGS,
 	  "Return a tuple of all breakpoint objects" },
 
+	{ "get_frames", gdbpy_get_frames, METH_NOARGS,
+	  "Return a tuple of all frame objects" },
+	{ "get_current_frame", gdbpy_get_current_frame, METH_NOARGS,
+	  "Return the current frame object" },
+	{ "get_selected_frame", gdbpy_get_selected_frame, METH_NOARGS,
+	  "Return the selected frame object" },
+	{ "frame_stop_reason_string", gdbpy_frame_stop_reason_string,
+	  METH_VARARGS, "Return a string explaining unwind stop reason" },
+
+	{ "solib_address", gdbpy_solib_address, METH_VARARGS,
+	  "Return shared library holding a given address, or None." },
+
 	{NULL, NULL, 0, NULL}
       };
 
@@ -70,6 +84,7 @@ demand_python ()
       gdbpy_initialize_hooks ();
       gdbpy_initialize_values ();
       gdbpy_initialize_breakpoints ();
+      gdbpy_initialize_frames ();
       gdbpy_initialize_commands ();
 
       PyRun_SimpleString ("import gdb");
@@ -327,6 +342,29 @@ value_of_python (char *expr, int length)
   return value;
 }
 
+PyObject *
+gdbpy_solib_address (PyObject *self, PyObject *args)
+{
+  unsigned long long pc;
+  char *soname;
+  PyObject *str_obj;
+
+  if (!PyArg_ParseTuple (args, "K", &pc))
+    return NULL;
+
+  soname = solib_address (pc);
+  if (soname)
+    str_obj = PyString_Decode (soname, strlen (soname), host_charset (),
+			       NULL /* FIXME */);
+  else
+    {
+      str_obj = Py_None;
+      Py_INCREF (Py_None);
+    }
+
+  return str_obj;
+}
+
 \f
 
 void
Index: tromey.git/gdb/stack.c
===================================================================
--- tromey.git.orig/gdb/stack.c	2008-04-29 10:57:39.000000000 -0300
+++ tromey.git/gdb/stack.c	2008-04-29 11:05:45.000000000 -0300
@@ -562,19 +562,16 @@ print_frame_info (struct frame_info *fra
   gdb_flush (gdb_stdout);
 }
 
-static void
-print_frame (struct frame_info *frame, int print_level,
-	     enum print_what print_what, int print_args,
-	     struct symtab_and_line sal)
+/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding
+   to FRAME.  */
+void
+find_frame_funname (struct frame_info *frame, char **funname,
+		    enum language *funlang)
 {
   struct symbol *func;
-  char *funname = NULL;
-  enum language funlang = language_unknown;
-  struct ui_stream *stb;
-  struct cleanup *old_chain, *list_chain;
 
-  stb = ui_out_stream_new (uiout);
-  old_chain = make_cleanup_ui_out_stream_delete (stb);
+  *funname = NULL;
+  *funlang = language_unknown;
 
   func = find_pc_function (get_frame_address_in_block (frame));
   if (func)
@@ -607,14 +604,14 @@ print_frame (struct frame_info *frame, i
 	  /* We also don't know anything about the function besides
 	     its address and name.  */
 	  func = 0;
-	  funname = DEPRECATED_SYMBOL_NAME (msymbol);
-	  funlang = SYMBOL_LANGUAGE (msymbol);
+	  *funname = DEPRECATED_SYMBOL_NAME (msymbol);
+	  *funlang = SYMBOL_LANGUAGE (msymbol);
 	}
       else
 	{
-	  funname = DEPRECATED_SYMBOL_NAME (func);
-	  funlang = SYMBOL_LANGUAGE (func);
-	  if (funlang == language_cplus)
+	  *funname = DEPRECATED_SYMBOL_NAME (func);
+	  *funlang = SYMBOL_LANGUAGE (func);
+	  if (*funlang == language_cplus)
 	    {
 	      /* It seems appropriate to use SYMBOL_PRINT_NAME() here,
 		 to display the demangled name that we already have
@@ -629,12 +626,12 @@ print_frame (struct frame_info *frame, i
 		 too. So we want to catch the failure (where DEMANGLED
 		 is NULL below) here, while we still have our hands on
 		 the function symbol.)  */
-	      char *demangled = cplus_demangle (funname, DMGL_ANSI);
+	      char *demangled = cplus_demangle (*funname, DMGL_ANSI);
 	      if (demangled == NULL)
 		/* If the demangler fails, try the demangled name from
 		   the symbol table. That'll have parameters, but
 		   that's preferable to displaying a mangled name.  */
-		funname = SYMBOL_PRINT_NAME (func);
+		*funname = SYMBOL_PRINT_NAME (func);
 	      else
 		xfree (demangled);
 	    }
@@ -647,10 +644,26 @@ print_frame (struct frame_info *frame, i
 
       if (msymbol != NULL)
 	{
-	  funname = DEPRECATED_SYMBOL_NAME (msymbol);
-	  funlang = SYMBOL_LANGUAGE (msymbol);
+	  *funname = DEPRECATED_SYMBOL_NAME (msymbol);
+	  *funlang = SYMBOL_LANGUAGE (msymbol);
 	}
     }
+}
+
+static void
+print_frame (struct frame_info *frame, int print_level,
+	     enum print_what print_what, int print_args,
+	     struct symtab_and_line sal)
+{
+  char *funname = NULL;
+  enum language funlang = language_unknown;
+  struct ui_stream *stb;
+  struct cleanup *old_chain, *list_chain;
+
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+  find_frame_funname (frame, &funname, &funlang);
 
   annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
 			get_frame_pc (frame));
@@ -685,7 +698,7 @@ print_frame (struct frame_info *frame, i
       struct print_args_args args;
       struct cleanup *args_list_chain;
       args.frame = frame;
-      args.func = func;
+      args.func = find_pc_function (get_frame_address_in_block (frame));
       args.stream = gdb_stdout;
       args_list_chain = make_cleanup_ui_out_list_begin_end (uiout, "args");
       catch_errors (print_args_stub, &args, "", RETURN_MASK_ERROR);
Index: tromey.git/gdb/stack.h
===================================================================
--- tromey.git.orig/gdb/stack.h	2008-04-29 10:57:39.000000000 -0300
+++ tromey.git/gdb/stack.h	2008-04-29 11:05:45.000000000 -0300
@@ -22,4 +22,9 @@
 
 void select_frame_command (char *level_exp, int from_tty);
 
+/* Attempt to obtain the FUNNAME and FUNLANG of the function corresponding
+   to FRAME.  */
+void find_frame_funname (struct frame_info *frame, char **funname,
+			 enum language *funlang);
+
 #endif /* #ifndef STACK_H */

-- 
-- 
[]'s
Thiago Jung Bauermann
Software Engineer
IBM Linux Technology Center


  parent reply	other threads:[~2008-04-29 15:58 UTC|newest]

Thread overview: 147+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-29 15:59 [RFC][patch 0/9] Python support in GDB Thiago Jung Bauermann
2008-04-29 15:59 ` [RFC][patch 8/9] export symtab mechanism to Python Thiago Jung Bauermann
2008-04-29 15:59 ` Thiago Jung Bauermann [this message]
2008-04-29 15:59 ` [RFC][patch 9/9] export threads " Thiago Jung Bauermann
2008-04-29 15:59 ` [RFC][patch 3/9] export hooks mechanism " Thiago Jung Bauermann
2008-04-29 21:29   ` Tom Tromey
2008-04-30 18:27     ` Joel Brobecker
2008-04-30 21:30       ` Tom Tromey
2008-05-27 18:22         ` Tom Tromey
2008-04-30 18:29     ` Daniel Jacobowitz
2008-04-30 23:00       ` Tom Tromey
2008-05-29  7:55   ` Daniel Jacobowitz
2008-05-30 14:59     ` Tom Tromey
2008-06-15 22:53       ` Thiago Jung Bauermann
2008-06-15 22:58         ` Tom Tromey
2008-06-16  3:22           ` Daniel Jacobowitz
2008-06-17 18:13             ` Thiago Jung Bauermann
2008-06-17 22:20               ` Joel Brobecker
2008-06-23 17:58                 ` Tom Tromey
2008-04-29 15:59 ` [RFC][patch 5/9] permit GDB commands implemented in Python Thiago Jung Bauermann
2008-04-29 16:08 ` [RFC][patch 7/9] export block and symbol mechanism to Python Thiago Jung Bauermann
2008-04-29 18:11 ` [RFC][patch 4/9] export breakpoints " Thiago Jung Bauermann
2008-04-29 18:15 ` [RFC][patch 1/9] initial Python support Thiago Jung Bauermann
2008-05-05  8:12   ` Thiago Jung Bauermann
2008-05-05 14:39     ` Daniel Jacobowitz
2008-05-05 14:46       ` Thiago Jung Bauermann
2008-05-05 16:50         ` Daniel Jacobowitz
2008-05-06  2:38           ` Thiago Jung Bauermann
2008-05-11 22:24           ` Thiago Jung Bauermann
2008-05-11 22:26             ` Daniel Jacobowitz
2008-05-12 20:33               ` Thiago Jung Bauermann
2008-05-12 20:39                 ` Daniel Jacobowitz
2008-05-12 21:00                   ` Thiago Jung Bauermann
2008-05-29  0:29   ` Daniel Jacobowitz
2008-05-30 13:07     ` Function syntax (Was: [RFC][patch 1/9] initial Python support) Tom Tromey
2008-06-08 15:24       ` Doug Evans
2008-06-08 15:32         ` Function syntax Tom Tromey
2008-06-08 18:21       ` Function syntax (Was: [RFC][patch 1/9] initial Python support) Daniel Jacobowitz
2008-06-09 13:48         ` Thiago Jung Bauermann
2008-06-09 18:43           ` Daniel Jacobowitz
2008-06-10  0:24             ` Function syntax Tom Tromey
2008-06-10  0:04           ` Tom Tromey
2008-06-11  0:04             ` Thiago Jung Bauermann
2008-06-10  0:00         ` Tom Tromey
2008-05-30 14:47     ` [RFC][patch 1/9] initial Python support Tom Tromey
2008-06-15 22:35     ` thiagoju
2008-06-23 17:36       ` Tom Tromey
2008-07-06 17:28         ` Tom Tromey
2008-07-08  4:12           ` Thiago Jung Bauermann
2008-07-15  7:38       ` [RFA] " Thiago Jung Bauermann
2008-07-15 17:19         ` Tom Tromey
2008-07-15 18:33           ` Thiago Jung Bauermann
2008-07-15 19:03             ` Tom Tromey
2008-07-16  7:14               ` Thiago Jung Bauermann
2008-07-16 14:39           ` Tom Tromey
2008-07-16 22:02             ` Thiago Jung Bauermann
2008-07-18 19:50               ` Daniel Jacobowitz
2008-07-18 23:24                 ` Tom Tromey
2008-07-19  0:45                   ` Daniel Jacobowitz
2008-07-19 19:50                 ` [RFA] iRe: " Thiago Jung Bauermann
2008-07-19 21:13                   ` Daniel Jacobowitz
2008-07-19 22:13                     ` Thiago Jung Bauermann
2008-07-20 23:47                   ` Thiago Jung Bauermann
2008-07-21  2:03                     ` Daniel Jacobowitz
2008-07-23 17:46                       ` [obvious] Wipe out CONFIG_INITS Thiago Jung Bauermann
2008-07-20 22:43                 ` [RFA] Re: [RFC][patch 1/9] initial Python support Tom Tromey
2008-07-21  1:59                   ` Daniel Jacobowitz
2008-07-21 15:29                 ` [RFA][patch 1/9] Yet another respin of the patch with " Thiago Jung Bauermann
2008-07-21 16:47                   ` Thiago Jung Bauermann
2008-07-26 13:07                   ` Eli Zaretskii
2008-07-26 13:43                     ` Daniel Jacobowitz
2008-07-26 14:02                       ` Eli Zaretskii
2008-07-26 14:42                         ` Daniel Jacobowitz
2008-07-26 17:06                           ` Eli Zaretskii
2008-07-26 17:26                             ` Tom Tromey
2008-07-26 19:21                               ` Eli Zaretskii
2008-07-26 17:40                             ` Daniel Jacobowitz
2008-07-26 17:10                           ` Tom Tromey
2008-07-26 17:40                             ` Eli Zaretskii
2008-07-26 18:00                               ` Tom Tromey
2008-07-26 18:29                                 ` Eli Zaretskii
2008-07-26 18:45                                   ` Tom Tromey
2008-07-26 19:34                                     ` Eli Zaretskii
2008-07-30 14:59                                       ` Thiago Jung Bauermann
2008-07-30 17:57                                         ` Eli Zaretskii
2008-08-04  4:44                                           ` Thiago Jung Bauermann
2008-08-04 19:18                                             ` Eli Zaretskii
2008-08-05  3:42                                               ` Thiago Jung Bauermann
2008-07-26 17:04                     ` Tom Tromey
2008-07-26 17:35                       ` Daniel Jacobowitz
2008-07-26 17:42                         ` Tom Tromey
2008-07-26 19:18                           ` Eli Zaretskii
2008-08-04  2:52                             ` Thiago Jung Bauermann
2008-08-04  3:22                               ` Eli Zaretskii
2008-08-04 12:15                                 ` Daniel Jacobowitz
2008-08-04 19:50                                   ` Eli Zaretskii
2008-08-05  2:08                                     ` Daniel Jacobowitz
2008-08-05  2:41                                       ` Thiago Jung Bauermann
2008-08-05  3:32                                       ` Eli Zaretskii
2008-08-05 12:19                                         ` Daniel Jacobowitz
2008-08-05 18:10                                           ` Eli Zaretskii
2008-08-05 18:23                                             ` Daniel Jacobowitz
2008-08-05 18:50                                               ` Eli Zaretskii
2008-08-05 18:58                                                 ` Daniel Jacobowitz
2008-07-26 19:20                         ` Eli Zaretskii
2008-07-26 18:11                       ` Eli Zaretskii
2008-07-26 18:30                         ` Daniel Jacobowitz
2008-07-26 19:26                           ` Eli Zaretskii
2008-08-01 20:04                           ` Tom Tromey
2008-08-02 17:38                             ` Daniel Jacobowitz
2008-08-02 17:50                               ` Tom Tromey
2008-08-02 19:00                               ` Eli Zaretskii
2008-08-05  4:19                         ` Thiago Jung Bauermann
2008-08-05 18:14                           ` Eli Zaretskii
2008-08-06  5:35                             ` [RFA][patch 1/9] Initial Python support, patch du jour Thiago Jung Bauermann
2008-08-06 18:24                               ` Eli Zaretskii
2008-08-06 19:53                                 ` Thiago Jung Bauermann
2008-08-04  4:44                     ` [RFA][patch 1/9] Yet another respin of the patch with initial Python support Thiago Jung Bauermann
2008-08-04 19:22                       ` Eli Zaretskii
2008-08-05  1:24                         ` Thiago Jung Bauermann
2008-08-02 17:41                   ` Daniel Jacobowitz
2008-08-02 19:02                     ` Eli Zaretskii
2008-08-02 19:07                       ` Daniel Jacobowitz
2008-07-15 18:01         ` [RFA] Re: [RFC][patch 1/9] " Thiago Jung Bauermann
2008-04-29 18:17 ` [RFC][patch 2/9] export values mechanism to Python Thiago Jung Bauermann
2008-05-29  1:23   ` Daniel Jacobowitz
2008-06-03  0:19     ` Tom Tromey
2008-06-03 13:04       ` Daniel Jacobowitz
2008-06-03 14:52         ` Tom Tromey
2008-07-07  6:03       ` Thiago Jung Bauermann
2008-07-07 23:44         ` Tom Tromey
2008-07-26  2:55           ` Daniel Jacobowitz
2008-07-26 17:17             ` Tom Tromey
2008-07-26 17:41               ` Daniel Jacobowitz
2008-07-30  3:01                 ` Tom Tromey
2008-07-30 14:26                   ` Thiago Jung Bauermann
2008-08-13  6:45         ` [python] acessing struct elements Thiago Jung Bauermann
2008-08-13 12:38           ` Daniel Jacobowitz
2008-08-13 20:38             ` Thiago Jung Bauermann
2008-08-17 20:16           ` Tom Tromey
2008-04-29 18:38 ` [RFC][patch 0/9] Python support in GDB Eli Zaretskii
2008-04-29 20:37   ` Thiago Jung Bauermann
2008-04-29 21:22     ` Tom Tromey
2008-04-30  7:54       ` Eli Zaretskii
2008-04-30 19:38         ` Thiago Jung Bauermann
2008-04-30 19:52           ` Eli Zaretskii
2008-05-02 18:30 ` Vladimir Prus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080429155305.189018566@br.ibm.com \
    --to=bauerman@br.ibm.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox