Fix some indentation in linespec.c
[deliverable/binutils-gdb.git] / gdb / python / py-unwind.c
index bcfea4bbe87bc20a3d40e0dc820b66a7ff681307..1d235fceed14b5e3eb72954fbdf8d5afc96cf334 100644 (file)
@@ -1,6 +1,6 @@
 /* Python frame unwinder interface.
 
-   Copyright (C) 2015 Free Software Foundation, Inc.
+   Copyright (C) 2015-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdb_obstack.h"
 #include "gdbcmd.h"
 #include "language.h"
-#include "observer.h"
+#include "observable.h"
 #include "python-internal.h"
 #include "regcache.h"
 #include "valprint.h"
 #include "user-regs.h"
+#include "py-ref.h"
 
 #define TRACE_PY_UNWIND(level, args...) if (pyuw_debug >= level)  \
   { fprintf_unfiltered (gdb_stdlog, args); }
@@ -83,20 +84,13 @@ typedef struct
   /* Length of the `reg' array below.  */
   int reg_count;
 
-  struct reg_info
-  {
-    /* Register number.  */
-    int number;
-
-    /* Register data bytes pointer.  */
-    gdb_byte data[MAX_REGISTER_SIZE];
-  } reg[];
+  cached_reg_t reg[];
 } cached_frame_info;
 
-static PyTypeObject pending_frame_object_type
+extern PyTypeObject pending_frame_object_type
     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("pending_frame_object");
 
-static PyTypeObject unwind_info_object_type
+extern PyTypeObject unwind_info_object_type
     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("unwind_info_object");
 
 static unsigned int pyuw_debug = 0;
@@ -114,12 +108,12 @@ pyuw_parse_register_id (struct gdbarch *gdbarch, PyObject *pyo_reg_id,
     return 0;
   if (gdbpy_is_string (pyo_reg_id))
     {
-      const char *reg_name = gdbpy_obj_to_string (pyo_reg_id);
+      gdb::unique_xmalloc_ptr<char> reg_name (gdbpy_obj_to_string (pyo_reg_id));
 
       if (reg_name == NULL)
         return 0;
-      *reg_num = user_reg_map_name_to_regnum (gdbarch, reg_name,
-                                              strlen (reg_name));
+      *reg_num = user_reg_map_name_to_regnum (gdbarch, reg_name.get (),
+                                              strlen (reg_name.get ()));
       return *reg_num >= 0;
     }
   else if (PyInt_Check (pyo_reg_id))
@@ -174,19 +168,17 @@ pyuw_object_attribute_to_pointer (PyObject *pyo, const char *attr_name,
 
   if (PyObject_HasAttrString (pyo, attr_name))
     {
-      PyObject *pyo_value = PyObject_GetAttrString (pyo, attr_name);
-      struct value *value;
+      gdbpy_ref<> pyo_value (PyObject_GetAttrString (pyo, attr_name));
 
       if (pyo_value != NULL && pyo_value != Py_None)
         {
-          rc = pyuw_value_obj_to_pointer (pyo_value, addr);
+          rc = pyuw_value_obj_to_pointer (pyo_value.get (), addr);
           if (!rc)
             PyErr_Format (
                 PyExc_ValueError,
                 _("The value of the '%s' attribute is not a pointer."),
                 attr_name);
         }
-      Py_XDECREF (pyo_value);
     }
   return rc;
 }
@@ -197,35 +189,30 @@ pyuw_object_attribute_to_pointer (PyObject *pyo, const char *attr_name,
 static PyObject *
 unwind_infopy_str (PyObject *self)
 {
-  struct ui_file *strfile = mem_fileopen ();
   unwind_info_object *unwind_info = (unwind_info_object *) self;
-  pending_frame_object *pending_frame
-      = (pending_frame_object *) (unwind_info->pending_frame);
-  PyObject *result;
+  string_file stb;
 
-  fprintf_unfiltered (strfile, "Frame ID: ");
-  fprint_frame_id (strfile, unwind_info->frame_id);
+  stb.puts ("Frame ID: ");
+  fprint_frame_id (&stb, unwind_info->frame_id);
   {
-    char *sep = "";
+    const char *sep = "";
     int i;
     struct value_print_options opts;
     saved_reg *reg;
 
     get_user_print_options (&opts);
-    fprintf_unfiltered (strfile, "\nSaved registers: (");
-    for (i = 0;
-         i < VEC_iterate (saved_reg, unwind_info->saved_regs, i, reg);
-         i++)
+    stb.printf ("\nSaved registers: (");
+    for (i = 0; VEC_iterate (saved_reg, unwind_info->saved_regs, i, reg); i++)
       {
         struct value *value = value_object_to_value (reg->value);
 
-        fprintf_unfiltered (strfile, "%s(%d, ", sep, reg->number);
+        stb.printf ("%s(%d, ", sep, reg->number);
         if (value != NULL)
           {
             TRY
               {
-                value_print (value, strfile, &opts);
-                fprintf_unfiltered (strfile, ")");
+                value_print (value, &stb, &opts);
+                stb.puts (")");
               }
             CATCH (except, RETURN_MASK_ALL)
               {
@@ -234,19 +221,13 @@ unwind_infopy_str (PyObject *self)
             END_CATCH
           }
         else
-          fprintf_unfiltered (strfile, "<BAD>)");
+          stb.puts ("<BAD>)");
         sep = ", ";
       }
-    fprintf_unfiltered (strfile, ")");
+    stb.puts (")");
   }
-  {
-    char *s = ui_file_xstrdup (strfile, NULL);
 
-    result = PyString_FromString (s);
-    xfree (s);
-  }
-  ui_file_delete (strfile);
-  return result;
+  return PyString_FromString (stb.c_str ());
 }
 
 /* Create UnwindInfo instance for given PendingFrame and frame ID.
@@ -413,7 +394,12 @@ pending_framepy_read_register (PyObject *self, PyObject *args)
 
   TRY
     {
-      val = get_frame_register_value (pending_frame->frame_info, regnum);
+      /* Fetch the value associated with a register, whether it's
+        a real register or a so called "user" register, like "pc",
+        which maps to a real register.  In the past,
+        get_frame_register_value() was used here, which did not
+        handle the user register case.  */
+      val = value_of_register (regnum, pending_frame->frame_info);
       if (val == NULL)
         PyErr_Format (PyExc_ValueError,
                       "Cannot read register %d from frame.",
@@ -466,15 +452,6 @@ pending_framepy_create_unwind_info (PyObject *self, PyObject *args)
                                     frame_id_build_special (sp, pc, special));
 }
 
-/* Invalidate PendingFrame instance.  */
-
-static void
-pending_frame_invalidate (void *pyo_pending_frame)
-{
-  if (pyo_pending_frame != NULL)
-    ((pending_frame_object *) pyo_pending_frame)->frame_info = NULL;
-}
-
 /* frame_unwind.this_id method.  */
 
 static void
@@ -496,15 +473,15 @@ static struct value *
 pyuw_prev_register (struct frame_info *this_frame, void **cache_ptr,
                     int regnum)
 {
-  cached_frame_info *cached_frame = *cache_ptr;
-  struct reg_info *reg_info = cached_frame->reg;
-  struct reg_info *reg_info_end = reg_info + cached_frame->reg_count;
+  cached_frame_info *cached_frame = (cached_frame_info *) *cache_ptr;
+  cached_reg_t *reg_info = cached_frame->reg;
+  cached_reg_t *reg_info_end = reg_info + cached_frame->reg_count;
 
   TRACE_PY_UNWIND (1, "%s (frame=%p,...,reg=%d)\n", __FUNCTION__, this_frame,
                    regnum);
   for (; reg_info < reg_info_end; ++reg_info)
     {
-      if (regnum == reg_info->number)
+      if (regnum == reg_info->num)
         return frame_unwind_got_bytes (this_frame, regnum, reg_info->data);
     }
 
@@ -518,25 +495,26 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
               void **cache_ptr)
 {
   struct gdbarch *gdbarch = (struct gdbarch *) (self->unwind_data);
-  struct cleanup *cleanups = ensure_python_env (gdbarch, current_language);
-  PyObject *pyo_execute;
-  PyObject *pyo_pending_frame;
-  PyObject *pyo_unwind_info;
   cached_frame_info *cached_frame;
 
+  gdbpy_enter enter_py (gdbarch, current_language);
+
   TRACE_PY_UNWIND (3, "%s (SP=%s, PC=%s)\n", __FUNCTION__,
                    paddress (gdbarch, get_frame_sp (this_frame)),
                    paddress (gdbarch, get_frame_pc (this_frame)));
 
   /* Create PendingFrame instance to pass to sniffers.  */
-  pyo_pending_frame  = (PyObject *) PyObject_New (pending_frame_object,
-                                                  &pending_frame_object_type);
+  pending_frame_object *pfo = PyObject_New (pending_frame_object,
+                                           &pending_frame_object_type);
+  gdbpy_ref<> pyo_pending_frame ((PyObject *) pfo);
   if (pyo_pending_frame == NULL)
-    goto error;
-  ((pending_frame_object *) pyo_pending_frame)->gdbarch = gdbarch;
-  ((pending_frame_object *) pyo_pending_frame)->frame_info = this_frame;
-  make_cleanup (pending_frame_invalidate, (void *) pyo_pending_frame);
-  make_cleanup_py_decref (pyo_pending_frame);
+    {
+      gdbpy_print_stack ();
+      return 0;
+    }
+  pfo->gdbarch = gdbarch;
+  scoped_restore invalidate_frame = make_scoped_restore (&pfo->frame_info,
+                                                        this_frame);
 
   /* Run unwinders.  */
   if (gdb_python_module == NULL
@@ -545,33 +523,51 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
       PyErr_SetString (PyExc_NameError,
                        "Installation error: gdb.execute_unwinders function "
                        "is missing");
-      goto error;
+      gdbpy_print_stack ();
+      return 0;
     }
-  pyo_execute = PyObject_GetAttrString (gdb_python_module, "execute_unwinders");
+  gdbpy_ref<> pyo_execute (PyObject_GetAttrString (gdb_python_module,
+                                                  "execute_unwinders"));
   if (pyo_execute == NULL)
-    goto error;
-  make_cleanup_py_decref (pyo_execute);
-  pyo_unwind_info
-      = PyObject_CallFunctionObjArgs (pyo_execute, pyo_pending_frame, NULL);
+    {
+      gdbpy_print_stack ();
+      return 0;
+    }
+
+  gdbpy_ref<> pyo_unwind_info
+    (PyObject_CallFunctionObjArgs (pyo_execute.get (),
+                                  pyo_pending_frame.get (), NULL));
   if (pyo_unwind_info == NULL)
-    goto error;
-  make_cleanup_py_decref (pyo_unwind_info);
+    {
+      /* If the unwinder is cancelled due to a Ctrl-C, then propagate
+        the Ctrl-C as a GDB exception instead of swallowing it.  */
+      if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
+       {
+         PyErr_Clear ();
+         quit ();
+       }
+      gdbpy_print_stack ();
+      return 0;
+    }
   if (pyo_unwind_info == Py_None)
-    goto cannot_unwind;
+    return 0;
 
   /* Received UnwindInfo, cache data.  */
-  if (PyObject_IsInstance (pyo_unwind_info,
+  if (PyObject_IsInstance (pyo_unwind_info.get (),
                            (PyObject *) &unwind_info_object_type) <= 0)
     error (_("A Unwinder should return gdb.UnwindInfo instance."));
 
   {
-    unwind_info_object *unwind_info = (unwind_info_object *) pyo_unwind_info;
+    unwind_info_object *unwind_info =
+      (unwind_info_object *) pyo_unwind_info.get ();
     int reg_count = VEC_length (saved_reg, unwind_info->saved_regs);
     saved_reg *reg;
     int i;
 
-    cached_frame = xmalloc (sizeof (*cached_frame) +
-                            reg_count * sizeof (cached_frame->reg[0]));
+    cached_frame
+      = ((cached_frame_info *)
+        xmalloc (sizeof (*cached_frame)
+                 + reg_count * sizeof (cached_frame->reg[0])));
     cached_frame->gdbarch = gdbarch;
     cached_frame->frame_id = unwind_info->frame_id;
     cached_frame->reg_count = reg_count;
@@ -582,27 +578,19 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
         struct value *value = value_object_to_value (reg->value);
         size_t data_size = register_size (gdbarch, reg->number);
 
-        cached_frame->reg[i].number = reg->number;
+       cached_frame->reg[i].num = reg->number;
 
         /* `value' validation was done before, just assert.  */
         gdb_assert (value != NULL);
         gdb_assert (data_size == TYPE_LENGTH (value_type (value)));
-        gdb_assert (data_size <= MAX_REGISTER_SIZE);
 
+       cached_frame->reg[i].data = (gdb_byte *) xmalloc (data_size);
         memcpy (cached_frame->reg[i].data, value_contents (value), data_size);
       }
   }
 
   *cache_ptr = cached_frame;
-  do_cleanups (cleanups);
   return 1;
-
- error:
-  gdbpy_print_stack ();
-  /* Fallthrough.  */
- cannot_unwind:
-  do_cleanups (cleanups);
-  return 0;
 }
 
 /* Frame cache release shim.  */
@@ -611,6 +599,11 @@ static void
 pyuw_dealloc_cache (struct frame_info *this_frame, void *cache)
 {
   TRACE_PY_UNWIND (3, "%s: enter", __FUNCTION__);
+  cached_frame_info *cached_frame = (cached_frame_info *) cache;
+
+  for (int i = 0; i < cached_frame->reg_count; i++)
+    xfree (cached_frame->reg[i].data);
+
   xfree (cache);
 }
 
@@ -632,8 +625,9 @@ pyuw_gdbarch_data_init (struct gdbarch *gdbarch)
 static void
 pyuw_on_new_gdbarch (struct gdbarch *newarch)
 {
-  struct pyuw_gdbarch_data_type *data =
-      gdbarch_data (newarch, pyuw_gdbarch_data);
+  struct pyuw_gdbarch_data_type *data
+    = (struct pyuw_gdbarch_data_type *) gdbarch_data (newarch,
+                                                     pyuw_gdbarch_data);
 
   if (!data->unwinder_registered)
     {
@@ -644,7 +638,7 @@ pyuw_on_new_gdbarch (struct gdbarch *newarch)
       unwinder->stop_reason = default_frame_unwind_stop_reason;
       unwinder->this_id = pyuw_this_id;
       unwinder->prev_register = pyuw_prev_register;
-      unwinder->unwind_data = (void *) newarch;
+      unwinder->unwind_data = (const struct frame_data *) newarch;
       unwinder->sniffer = pyuw_sniffer;
       unwinder->dealloc_cache = pyuw_dealloc_cache;
       frame_unwind_prepend_unwinder (newarch, unwinder);
@@ -668,7 +662,7 @@ gdbpy_initialize_unwind (void)
         &setdebuglist, &showdebuglist);
   pyuw_gdbarch_data
       = gdbarch_data_register_post_init (pyuw_gdbarch_data_init);
-  observer_attach_architecture_changed (pyuw_on_new_gdbarch);
+  gdb::observers::architecture_changed.attach (pyuw_on_new_gdbarch);
 
   if (PyType_Ready (&pending_frame_object_type) < 0)
     return -1;
@@ -696,7 +690,7 @@ static PyMethodDef pending_frame_object_methods[] =
   {NULL}  /* Sentinel */
 };
 
-static PyTypeObject pending_frame_object_type =
+PyTypeObject pending_frame_object_type =
 {
   PyVarObject_HEAD_INIT (NULL, 0)
   "gdb.PendingFrame",             /* tp_name */
@@ -746,7 +740,7 @@ static PyMethodDef unwind_info_object_methods[] =
   { NULL }  /* Sentinel */
 };
 
-static PyTypeObject unwind_info_object_type =
+PyTypeObject unwind_info_object_type =
 {
   PyVarObject_HEAD_INIT (NULL, 0)
   "gdb.UnwindInfo",               /* tp_name */
This page took 0.02875 seconds and 4 git commands to generate.