Fix some indentation in linespec.c
[deliverable/binutils-gdb.git] / gdb / python / py-unwind.c
index 2c2a0f93e4c0923a8f15c40004171d23c8cc8d08..1d235fceed14b5e3eb72954fbdf8d5afc96cf334 100644 (file)
@@ -1,6 +1,6 @@
 /* Python frame unwinder interface.
 
-   Copyright (C) 2015-2017 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); }
@@ -72,15 +73,6 @@ typedef struct
 /* The data we keep for a frame we can unwind: frame ID and an array of
    (register_number, register_value) pairs.  */
 
-struct reg_info
-{
-  /* Register number.  */
-  int number;
-
-  /* Register data bytes pointer.  */
-  gdb_byte data[MAX_REGISTER_SIZE];
-};
-
 typedef struct
 {
   /* Frame ID.  */
@@ -92,7 +84,7 @@ typedef struct
   /* Length of the `reg' array below.  */
   int reg_count;
 
-  struct reg_info reg[];
+  cached_reg_t reg[];
 } cached_frame_info;
 
 extern PyTypeObject pending_frame_object_type
@@ -176,18 +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);
+      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;
 }
@@ -198,31 +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;
-  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: (");
+    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)
               {
@@ -231,16 +221,13 @@ unwind_infopy_str (PyObject *self)
             END_CATCH
           }
         else
-          fprintf_unfiltered (strfile, "<BAD>)");
+          stb.puts ("<BAD>)");
         sep = ", ";
       }
-    fprintf_unfiltered (strfile, ")");
+    stb.puts (")");
   }
 
-  std::string s = ui_file_as_string (strfile);
-  result = PyString_FromString (s.c_str ());
-  ui_file_delete (strfile);
-  return result;
+  return PyString_FromString (stb.c_str ());
 }
 
 /* Create UnwindInfo instance for given PendingFrame and frame ID.
@@ -465,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,14 +474,14 @@ pyuw_prev_register (struct frame_info *this_frame, void **cache_ptr,
                     int regnum)
 {
   cached_frame_info *cached_frame = (cached_frame_info *) *cache_ptr;
-  struct reg_info *reg_info = cached_frame->reg;
-  struct reg_info *reg_info_end = reg_info + cached_frame->reg_count;
+  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);
     }
 
@@ -517,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_py_decref (pyo_pending_frame);
-  make_cleanup (pending_frame_invalidate, (void *) 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
@@ -544,27 +523,43 @@ 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;
@@ -583,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.  */
@@ -612,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);
 }
 
@@ -670,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;
This page took 0.028298 seconds and 4 git commands to generate.