diff --git a/gdb/ctf.c b/gdb/ctf.c
index bef6f30..21ed113 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -1635,10 +1635,10 @@ ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num,
    frame, extract memory range information, and return them in
    traceframe_info.  */
 
-static struct traceframe_info *
+static traceframe_info_up
 ctf_traceframe_info (struct target_ops *self)
 {
-  traceframe_info *info = new traceframe_info;
+  traceframe_info_up info (new traceframe_info);
   const char *name;
   struct bt_iter_pos *pos;
 
diff --git a/gdb/remote.c b/gdb/remote.c
index 3ceabcf..c1a0228 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -13061,7 +13061,7 @@ remote_set_circular_trace_buffer (struct target_ops *self, int val)
     error (_("Bogus reply from target: %s"), reply);
 }
 
-static struct traceframe_info *
+static traceframe_info_up
 remote_traceframe_info (struct target_ops *self)
 {
   char *text;
@@ -13070,10 +13070,9 @@ remote_traceframe_info (struct target_ops *self)
 			       TARGET_OBJECT_TRACEFRAME_INFO, NULL);
   if (text != NULL)
     {
-      struct traceframe_info *info;
       struct cleanup *back_to = make_cleanup (xfree, text);
+      traceframe_info_up info = parse_traceframe_info (text);
 
-      info = parse_traceframe_info (text);
       do_cleanups (back_to);
       return info;
     }
diff --git a/gdb/target-debug.h b/gdb/target-debug.h
index 7477ce6..580ecd4 100644
--- a/gdb/target-debug.h
+++ b/gdb/target-debug.h
@@ -164,6 +164,8 @@
   target_debug_do_print (plongest (X))
 #define target_debug_print_gdb_disassembly_flags(X) \
   target_debug_do_print (plongest (X))
+#define target_debug_print_traceframe_info_up(X) \
+  target_debug_do_print (host_address_to_string (X.get ()))
 
 static void
 target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index c981796..00efbb1 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -3357,29 +3357,29 @@ debug_static_tracepoint_markers_by_strid (struct target_ops *self, const char *a
   return result;
 }
 
-static struct traceframe_info *
+static traceframe_info_up
 delegate_traceframe_info (struct target_ops *self)
 {
   self = self->beneath;
   return self->to_traceframe_info (self);
 }
 
-static struct traceframe_info *
+static traceframe_info_up
 tdefault_traceframe_info (struct target_ops *self)
 {
   tcomplain ();
 }
 
-static struct traceframe_info *
+static traceframe_info_up
 debug_traceframe_info (struct target_ops *self)
 {
-  struct traceframe_info * result;
+  traceframe_info_up result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->to_traceframe_info (...)\n", debug_target.to_shortname);
   result = debug_target.to_traceframe_info (&debug_target);
   fprintf_unfiltered (gdb_stdlog, "<- %s->to_traceframe_info (", debug_target.to_shortname);
   target_debug_print_struct_target_ops_p (&debug_target);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_struct_traceframe_info_p (result);
+  target_debug_print_traceframe_info_up (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
diff --git a/gdb/target.h b/gdb/target.h
index f5ad1e5..581c89b 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -76,6 +76,7 @@ struct inferior;
 #include "record.h"
 #include "command.h"
 #include "disasm.h"
+#include "tracepoint.h"
 
 #include "break-common.h" /* For enum target_hw_bp_type.  */
 
@@ -235,18 +236,6 @@ enum target_xfer_status
 extern const char *
   target_xfer_status_to_string (enum target_xfer_status status);
 
-/* Enumeration of the kinds of traceframe searches that a target may
-   be able to perform.  */
-
-enum trace_find_type
-  {
-    tfind_number,
-    tfind_pc,
-    tfind_tp,
-    tfind_range,
-    tfind_outside,
-  };
-
 typedef struct static_tracepoint_marker *static_tracepoint_marker_p;
 DEF_VEC_P(static_tracepoint_marker_p);
 
@@ -1116,8 +1105,8 @@ struct target_ops
        traceframe's contents.  This method should not cache data;
        higher layers take care of caching, invalidating, and
        re-fetching when necessary.  */
-    struct traceframe_info *(*to_traceframe_info) (struct target_ops *)
-	TARGET_DEFAULT_NORETURN (tcomplain ());
+    traceframe_info_up (*to_traceframe_info) (struct target_ops *)
+      TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Ask the target to use or not to use agent according to USE.  Return 1
        successful, 0 otherwise.  */
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index cc77b6c..727570c 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -1088,12 +1088,13 @@ build_traceframe_info (char blocktype, void *data)
   return 0;
 }
 
-static struct traceframe_info *
+static traceframe_info_up
 tfile_traceframe_info (struct target_ops *self)
 {
-  traceframe_info *info = new traceframe_info;
+  traceframe_info_up info (new traceframe_info);
+
+  traceframe_walk_blocks (build_traceframe_info, 0, info.get ());
 
-  traceframe_walk_blocks (build_traceframe_info, 0, info);
   return info;
 }
 
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 9f0d07b..8264632 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -133,7 +133,7 @@ static int tracepoint_number;
    yet attempted to fetch it, or if the target does not support
    fetching this object, or if we're not inspecting a traceframe
    presently.  */
-static struct traceframe_info *current_traceframe_info;
+static traceframe_info_up current_traceframe_info;
 
 /* Tracing command lists.  */
 static struct cmd_list_element *tfindlist;
@@ -191,21 +191,12 @@ current_trace_status (void)
   return &trace_status;
 }
 
-/* Destroy INFO.  */
-
-static void
-free_traceframe_info (struct traceframe_info *info)
-{
-  delete info;
-}
-
 /* Free and clear the traceframe info cache of the current
    traceframe.  */
 
 static void
 clear_traceframe_info (void)
 {
-  free_traceframe_info (current_traceframe_info);
   current_traceframe_info = NULL;
 }
 
@@ -4020,16 +4011,6 @@ traceframe_info_start_tvar (struct gdb_xml_parser *parser,
   info->tvars.push_back (id);
 }
 
-/* Discard the constructed trace frame info (if an error occurs).  */
-
-static void
-free_result (void *p)
-{
-  struct traceframe_info *result = (struct traceframe_info *) p;
-
-  free_traceframe_info (result);
-}
-
 /* The allowed elements and attributes for an XML memory map.  */
 
 static const struct gdb_xml_attribute memory_attributes[] = {
@@ -4061,25 +4042,16 @@ static const struct gdb_xml_element traceframe_info_elements[] = {
 
 /* Parse a traceframe-info XML document.  */
 
-struct traceframe_info *
+traceframe_info_up
 parse_traceframe_info (const char *tframe_info)
 {
-  traceframe_info *result = new traceframe_info;
-  struct cleanup *back_to;
-
-  back_to = make_cleanup (free_result, result);
+  traceframe_info_up result (new traceframe_info);
 
   if (gdb_xml_parse_quick (_("trace frame info"),
 			   "traceframe-info.dtd", traceframe_info_elements,
-			   tframe_info, result) == 0)
-    {
-      /* Parsed successfully, keep the result.  */
-      discard_cleanups (back_to);
-
-      return result;
-    }
+			   tframe_info, result.get ()) == 0)
+    return result;
 
-  do_cleanups (back_to);
   return NULL;
 }
 
@@ -4095,7 +4067,7 @@ get_traceframe_info (void)
   if (current_traceframe_info == NULL)
     current_traceframe_info = target_traceframe_info ();
 
-  return current_traceframe_info;
+  return current_traceframe_info.get ();
 }
 
 /* If the target supports the query, return in RESULT the set of
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index 872681d..88c18c3 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -20,7 +20,6 @@
 #define TRACEPOINT_H 1
 
 #include "breakpoint.h"
-#include "target.h"
 #include "memrange.h"
 #include "gdb_vecs.h"
 
@@ -38,6 +37,8 @@ struct traceframe_info
   std::vector<int> tvars;
 };
 
+typedef std::unique_ptr<traceframe_info> traceframe_info_up;
+
 /* A trace state variable is a value managed by a target being
    traced.  A trace state variable (or tsv for short) can be accessed
    and assigned to by tracepoint actions and conditionals, but is not
@@ -376,6 +377,18 @@ extern void trace_status_mi (int on_stop);
 extern void tvariables_info_1 (void);
 extern void save_trace_state_variables (struct ui_file *fp);
 
+/* Enumeration of the kinds of traceframe searches that a target may
+   be able to perform.  */
+
+enum trace_find_type
+{
+  tfind_number,
+  tfind_pc,
+  tfind_tp,
+  tfind_range,
+  tfind_outside,
+};
+
 extern void tfind_1 (enum trace_find_type type, int num,
 		     CORE_ADDR addr1, CORE_ADDR addr2,
 		     int from_tty);
@@ -385,7 +398,7 @@ extern void trace_save_tfile (const char *filename,
 extern void trace_save_ctf (const char *dirname,
 			    int target_does_save);
 
-extern struct traceframe_info *parse_traceframe_info (const char *tframe_info);
+extern traceframe_info_up parse_traceframe_info (const char *tframe_info);
 
 extern int traceframe_available_memory (VEC(mem_range_s) **result,
 					CORE_ADDR memaddr, ULONGEST len);
