diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 143d77cb223..282eb0864a7 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -841,13 +841,15 @@ cp_print_value (struct type *type, struct type *real_type,
 	      /* Attempt to run an extension language pretty-printer on the
 		 baseclass if possible.  */
 	      if (!options->raw)
-		result
-		  = apply_ext_lang_val_pretty_printer (baseclass,
-						       thisoffset + boffset,
-						       value_address (base_val),
-						       stream, recurse,
-						       base_val, options,
-						       current_language);
+		{
+		  struct value *v
+		    = value_from_component (base_val, baseclass,
+					    thisoffset + boffset);
+		  result
+		    = apply_ext_lang_val_pretty_printer (v, stream, recurse,
+							 options,
+							 current_language);
+		}
 
 	      if (!result)
 		cp_print_value_fields (baseclass, thistype,
@@ -999,19 +1001,19 @@ cp_print_value (struct value *val, struct ui_file *stream,
 	    }
 	  else
 	    {
+	      struct value *baseclass_val = value_primitive_field (val, 0,
+								   i, type);
+
 	      /* Attempt to run an extension language pretty-printer on the
 		 baseclass if possible.  */
 	      if (!options->raw)
 		result
-		  = apply_ext_lang_val_pretty_printer (baseclass, boffset,
-						       value_address (base_val),
-						       stream, recurse,
-						       base_val, options,
+		  = apply_ext_lang_val_pretty_printer (baseclass_val, stream,
+						       recurse, options,
 						       current_language);
 
 	      if (!result)
-		cp_print_value_fields (value_primitive_field (val, 0, i, type),
-				       stream, recurse, options,
+		cp_print_value_fields (baseclass_val, stream, recurse, options,
 				       ((struct type **)
 					obstack_base (&dont_print_vb_obstack)),
 				       0);
diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h
index 97594f853a2..694df278aad 100644
--- a/gdb/extension-priv.h
+++ b/gdb/extension-priv.h
@@ -152,19 +152,14 @@ struct extension_language_ops
   void (*free_type_printers) (const struct extension_language_defn *,
 			      struct ext_lang_type_printers *);
 
-  /* Try to pretty-print a value of type TYPE located at VAL's contents
-     buffer + EMBEDDED_OFFSET, which came from the inferior at address
-     ADDRESS + EMBEDDED_OFFSET, onto stdio stream STREAM according to
-     OPTIONS.
-     VAL is the whole object that came from ADDRESS.
-     Returns EXT_LANG_RC_OK upon success, EXT_LANG_RC_NOP if the value
-     is not recognized, and EXT_LANG_RC_ERROR if an error was encountered.  */
+  /* Try to pretty-print a value, onto stdio stream STREAM according
+     to OPTIONS.  VAL is the object to print.  Returns EXT_LANG_RC_OK
+     upon success, EXT_LANG_RC_NOP if the value is not recognized, and
+     EXT_LANG_RC_ERROR if an error was encountered.  */
   enum ext_lang_rc (*apply_val_pretty_printer)
     (const struct extension_language_defn *,
-     struct type *type,
-     LONGEST embedded_offset, CORE_ADDR address,
-     struct ui_file *stream, int recurse,
-     struct value *val, const struct value_print_options *options,
+     struct value *val, struct ui_file *stream, int recurse,
+     const struct value_print_options *options,
      const struct language_defn *language);
 
   /* GDB access to the "frame filter" feature.
diff --git a/gdb/extension.c b/gdb/extension.c
index 1fb4b48003a..4ece206cc37 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -470,12 +470,9 @@ ext_lang_type_printers::~ext_lang_type_printers ()
     }
 }
 
-/* Try to pretty-print a value of type TYPE located at VAL's contents
-   buffer + EMBEDDED_OFFSET, which came from the inferior at address
-   ADDRESS + EMBEDDED_OFFSET, onto stdio stream STREAM according to
-   OPTIONS.
-   VAL is the whole object that came from ADDRESS.
-   Returns non-zero if the value was successfully pretty-printed.
+/* Try to pretty-print a value onto stdio stream STREAM according to
+   OPTIONS.  VAL is the object to print.  Returns non-zero if the
+   value was successfully pretty-printed.
 
    Extension languages are tried in the order specified by
    extension_languages.  The first one to provide a pretty-printed
@@ -488,10 +485,8 @@ ext_lang_type_printers::~ext_lang_type_printers ()
    errors that trigger an exception in the extension language.  */
 
 int
-apply_ext_lang_val_pretty_printer (struct type *type,
-				   LONGEST embedded_offset, CORE_ADDR address,
+apply_ext_lang_val_pretty_printer (struct value *val,
 				   struct ui_file *stream, int recurse,
-				   struct value *val,
 				   const struct value_print_options *options,
 				   const struct language_defn *language)
 {
@@ -504,10 +499,8 @@ apply_ext_lang_val_pretty_printer (struct type *type,
 
       if (extlang->ops->apply_val_pretty_printer == NULL)
 	continue;
-      rc = extlang->ops->apply_val_pretty_printer (extlang, type,
-						   embedded_offset, address,
-						   stream, recurse, val,
-						   options, language);
+      rc = extlang->ops->apply_val_pretty_printer (extlang, val, stream,
+						   recurse, options, language);
       switch (rc)
 	{
 	case EXT_LANG_RC_OK:
diff --git a/gdb/extension.h b/gdb/extension.h
index fc8e3e2c0ba..bf6fd3e3e58 100644
--- a/gdb/extension.h
+++ b/gdb/extension.h
@@ -282,10 +282,8 @@ extern char *apply_ext_lang_type_printers (struct ext_lang_type_printers *,
 					   struct type *);
 
 extern int apply_ext_lang_val_pretty_printer
-  (struct type *type,
-   LONGEST embedded_offset, CORE_ADDR address,
-   struct ui_file *stream, int recurse,
-   struct value *val, const struct value_print_options *options,
+  (struct value *value, struct ui_file *stream, int recurse,
+   const struct value_print_options *options,
    const struct language_defn *language);
 
 extern enum ext_lang_bt_status apply_ext_lang_frame_filter
diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h
index 3ae6618a7bc..3444c406d55 100644
--- a/gdb/guile/guile-internal.h
+++ b/gdb/guile/guile-internal.h
@@ -579,6 +579,7 @@ extern struct value *vlscm_scm_to_value (SCM scm);
 extern int vlscm_is_value (SCM scm);
 
 extern SCM vlscm_scm_from_value (struct value *value);
+extern SCM vlscm_scm_from_value_no_release (struct value *value);
 
 extern struct value *vlscm_convert_typed_value_from_scheme
   (const char *func_name, int obj_arg_pos, SCM obj,
@@ -602,10 +603,8 @@ extern void gdbscm_preserve_values
 
 extern enum ext_lang_rc gdbscm_apply_val_pretty_printer
   (const struct extension_language_defn *,
-   struct type *type,
-   LONGEST embedded_offset, CORE_ADDR address,
-   struct ui_file *stream, int recurse,
    struct value *val,
+   struct ui_file *stream, int recurse,
    const struct value_print_options *options,
    const struct language_defn *language);
 
diff --git a/gdb/guile/scm-pretty-print.c b/gdb/guile/scm-pretty-print.c
index 630a062148e..e7289a71786 100644
--- a/gdb/guile/scm-pretty-print.c
+++ b/gdb/guile/scm-pretty-print.c
@@ -943,36 +943,32 @@ ppscm_print_children (SCM printer, enum display_hint hint,
 
 enum ext_lang_rc
 gdbscm_apply_val_pretty_printer (const struct extension_language_defn *extlang,
-				 struct type *type,
-				 LONGEST embedded_offset, CORE_ADDR address,
+				 struct value *value,
 				 struct ui_file *stream, int recurse,
-				 struct value *val,
 				 const struct value_print_options *options,
 				 const struct language_defn *language)
 {
+  struct type *type = value_type (value);
   struct gdbarch *gdbarch = get_type_arch (type);
   SCM exception = SCM_BOOL_F;
   SCM printer = SCM_BOOL_F;
   SCM val_obj = SCM_BOOL_F;
-  struct value *value;
   enum display_hint hint;
   enum ext_lang_rc result = EXT_LANG_RC_NOP;
   enum string_repr_result print_result;
 
-  if (value_lazy (val))
-    value_fetch_lazy (val);
+  if (value_lazy (value))
+    value_fetch_lazy (value);
 
   /* No pretty-printer support for unavailable values.  */
-  if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+  if (!value_bytes_available (value, 0, TYPE_LENGTH (type)))
     return EXT_LANG_RC_NOP;
 
   if (!gdb_scheme_initialized)
     return EXT_LANG_RC_NOP;
 
   /* Instantiate the printer.  */
-  value = value_from_component (val, type, embedded_offset);
-
-  val_obj = vlscm_scm_from_value (value);
+  val_obj = vlscm_scm_from_value_no_release (value);
   if (gdbscm_is_exception (val_obj))
     {
       exception = val_obj;
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 8aa4cfa345b..7398a2d8332 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -261,6 +261,24 @@ vlscm_scm_from_value (struct value *value)
   return v_scm;
 }
 
+/* Create a new <gdb:value> object that encapsulates VALUE.
+   The value is not released from the all_values chain.  */
+
+SCM
+vlscm_scm_from_value_no_release (struct value *value)
+{
+  /* N.B. It's important to not cause any side-effects until we know the
+     conversion worked.  */
+  SCM v_scm = vlscm_make_value_smob ();
+  value_smob *v_smob = (value_smob *) SCM_SMOB_DATA (v_scm);
+
+  value_incref (value);
+  v_smob->value = value;
+  vlscm_remember_scheme_value (v_smob);
+
+  return v_scm;
+}
+
 /* Returns the <gdb:value> object in SELF.
    Throws an exception if SELF is not a <gdb:value> object.  */
 
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index a4df48fe19a..a5aed9c91ac 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -558,22 +558,20 @@ print_children (PyObject *printer, const char *hint,
 
 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 value *value,
 				struct ui_file *stream, int recurse,
-				struct value *val,
 				const struct value_print_options *options,
 				const struct language_defn *language)
 {
+  struct type *type = value_type (value);
   struct gdbarch *gdbarch = get_type_arch (type);
-  struct value *value;
   enum string_repr_result print_result;
 
-  if (value_lazy (val))
-    value_fetch_lazy (val);
+  if (value_lazy (value))
+    value_fetch_lazy (value);
 
   /* No pretty-printer support for unavailable values.  */
-  if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+  if (!value_bytes_available (value, 0, TYPE_LENGTH (type)))
     return EXT_LANG_RC_NOP;
 
   if (!gdb_python_initialized)
@@ -581,10 +579,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
 
   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));
+  gdbpy_ref<> val_obj (value_to_value_object_no_release (value));
   if (val_obj == NULL)
     {
       print_stack_unless_memory_error (stream);
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 1ca2dc5c719..5a967329f2d 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1788,6 +1788,27 @@ value_to_value_object (struct value *val)
   return (PyObject *) val_obj;
 }
 
+/* Returns an object for a value, but without releasing it from the
+   all_values chain.  */
+PyObject *
+value_to_value_object_no_release (struct value *val)
+{
+  value_object *val_obj;
+
+  val_obj = PyObject_New (value_object, &value_object_type);
+  if (val_obj != NULL)
+    {
+      value_incref (val);
+      val_obj->value = val;
+      val_obj->address = NULL;
+      val_obj->type = NULL;
+      val_obj->dynamic_type = NULL;
+      note_value (val_obj);
+    }
+
+  return (PyObject *) val_obj;
+}
+
 /* Returns a borrowed reference to the struct value corresponding to
    the given value object.  */
 struct value *
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 703c60032c0..a60af21458e 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -391,10 +391,8 @@ extern int gdbpy_auto_load_enabled (const struct extension_language_defn *);
 
 extern enum ext_lang_rc gdbpy_apply_val_pretty_printer
   (const struct extension_language_defn *,
-   struct type *type,
-   LONGEST embedded_offset, CORE_ADDR address,
+   struct value *value,
    struct ui_file *stream, int recurse,
-   struct value *val,
    const struct value_print_options *options,
    const struct language_defn *language);
 extern enum ext_lang_bt_status gdbpy_apply_frame_filter
@@ -454,6 +452,7 @@ PyObject *symbol_to_symbol_object (struct symbol *sym);
 PyObject *block_to_block_object (const struct block *block,
 				 struct objfile *objfile);
 PyObject *value_to_value_object (struct value *v);
+PyObject *value_to_value_object_no_release (struct value *v);
 PyObject *type_to_type_object (struct type *);
 PyObject *frame_info_to_frame_object (struct frame_info *frame);
 PyObject *symtab_to_linetable_object (PyObject *symtab);
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 251eae2d844..56f06be6b9c 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -1253,9 +1253,13 @@ do_val_print (struct value *full_value,
 
   if (!options->raw)
     {
-      ret = apply_ext_lang_val_pretty_printer (type, embedded_offset,
-					       address, stream, recurse,
-					       val, options, language);
+      struct value *v = full_value;
+
+      if (v == nullptr)
+	v = value_from_component (val, type, embedded_offset);
+
+      ret = apply_ext_lang_val_pretty_printer (v, stream, recurse, options,
+					       language);
       if (ret)
 	return;
     }
@@ -1451,11 +1455,8 @@ value_print (struct value *val, struct ui_file *stream,
   if (!options->raw)
     {
       int r
-	= apply_ext_lang_val_pretty_printer (value_type (val),
-					     value_embedded_offset (val),
-					     value_address (val),
-					     stream, 0,
-					     val, options, current_language);
+	= apply_ext_lang_val_pretty_printer (val, stream, 0, options,
+					     current_language);
 
       if (r)
 	return;
