Beispiel #1
0
enum ext_lang_rc
gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
				struct type *type,
				LONGEST embedded_offset, CORE_ADDR address,
				struct ui_file *stream, int recurse,
				struct value *val,
				const struct value_print_options *options,
				const struct language_defn *language)
{
  struct gdbarch *gdbarch = get_type_arch (type);
  struct value *value;
  enum string_repr_result print_result;

  if (value_lazy (val))
    value_fetch_lazy (val);

  /* No pretty-printer support for unavailable values.  */
  if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
    return EXT_LANG_RC_NOP;

  if (!gdb_python_initialized)
    return EXT_LANG_RC_NOP;

  gdbpy_enter enter_py (gdbarch, language);

  /* Instantiate the printer.  */
  value = value_from_component (val, type, embedded_offset);

  gdbpy_ref<> val_obj (value_to_value_object (value));
  if (val_obj == NULL)
    {
      print_stack_unless_memory_error (stream);
      return EXT_LANG_RC_ERROR;
    }

  /* Find the constructor.  */
  gdbpy_ref<> printer (find_pretty_printer (val_obj.get ()));
  if (printer == NULL)
    {
      print_stack_unless_memory_error (stream);
      return EXT_LANG_RC_ERROR;
    }

  if (printer == Py_None)
    return EXT_LANG_RC_NOP;

  /* If we are printing a map, we want some special formatting.  */
  gdb::unique_xmalloc_ptr<char> hint (gdbpy_get_display_hint (printer.get ()));

  /* Print the section */
  print_result = print_string_repr (printer.get (), hint.get (), stream,
				    recurse, options, language, gdbarch);
  if (print_result != string_repr_error)
    print_children (printer.get (), hint.get (), stream, recurse, options,
		    language, print_result == string_repr_none);

  if (PyErr_Occurred ())
    print_stack_unless_memory_error (stream);
  return EXT_LANG_RC_OK;
}
Beispiel #2
0
static void
py_free_pspace (struct program_space *pspace, void *datum)
{
  /* This is a fiction, but we're in a nasty spot: The pspace is in the
     process of being deleted, we can't rely on anything in it.  Plus
     this is one time when the current program space and current inferior
     are not in sync: All inferiors that use PSPACE may no longer exist.
     We don't need to do much here, and since "there is always an inferior"
     using target_gdbarch suffices.
     Note: We cannot call get_current_arch because it may try to access
     the target, which may involve accessing data in the pspace currently
     being deleted.  */
  struct gdbarch *arch = target_gdbarch ();

  gdbpy_enter enter_py (arch, current_language);
  gdbpy_ref<pspace_object> object ((pspace_object *) datum);
  object->pspace = NULL;
}
Beispiel #3
0
static struct value *
fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
	   void *cookie, int argc, struct value **argv)
{
  /* The gdbpy_enter object needs to be placed first, so that it's the last to
     be destroyed.  */
  gdbpy_enter enter_py (gdbarch, language);
  struct value *value;
  gdbpy_ref<> result;
  gdbpy_ref<> args (convert_values_to_python (argc, argv));

  /* convert_values_to_python can return NULL on error.  If we
     encounter this, do not call the function, but allow the Python ->
     error code conversion below to deal with the Python exception.
     Note, that this is different if the function simply does not
     have arguments.  */

  if (args != NULL)
    {
      gdbpy_ref<> callable (PyObject_GetAttrString ((PyObject *) cookie,
						    "invoke"));
      if (callable == NULL)
	error (_("No method named 'invoke' in object."));

      result.reset (PyObject_Call (callable.get (), args.get (), NULL));
    }

  if (result == NULL)
    {
      PyObject *ptype, *pvalue, *ptraceback;

      PyErr_Fetch (&ptype, &pvalue, &ptraceback);

      /* Try to fetch an error message contained within ptype, pvalue.
	 When fetching the error message we need to make our own copy,
	 we no longer own ptype, pvalue after the call to PyErr_Restore.  */

      gdb::unique_xmalloc_ptr<char>
	msg (gdbpy_exception_to_string (ptype, pvalue));

      if (msg == NULL)
	{
	  /* An error occurred computing the string representation of the
	     error message.  This is rare, but we should inform the user.  */

	  printf_filtered (_("An error occurred in a Python "
			     "convenience function\n"
			     "and then another occurred computing the "
			     "error message.\n"));
	  gdbpy_print_stack ();
	}

      /* Don't print the stack for gdb.GdbError exceptions.
	 It is generally used to flag user errors.

	 We also don't want to print "Error occurred in Python command"
	 for user errors.  However, a missing message for gdb.GdbError
	 exceptions is arguably a bug, so we flag it as such.  */

      if (!PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc)
	  || msg == NULL || *msg == '\0')
	{
	  PyErr_Restore (ptype, pvalue, ptraceback);
	  gdbpy_print_stack ();
	  if (msg != NULL && *msg != '\0')
	    error (_("Error occurred in Python convenience function: %s"),
		   msg.get ());
	  else
	    error (_("Error occurred in Python convenience function."));
	}
      else
	{
	  Py_XDECREF (ptype);
	  Py_XDECREF (pvalue);
	  Py_XDECREF (ptraceback);
	  error ("%s", msg.get ());
	}
    }

  value = convert_value_from_python (result.get ());
  if (value == NULL)
    {
      gdbpy_print_stack ();
      error (_("Error while executing Python code."));
    }

  return value;
}