diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 704de48..66e9236 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@
 2016-09-26  Tom Tromey  <tom@tromey.com>
 
+	* maint.h (scoped_command_stats): New class.
+	(make_command_stats_cleanup): Don't declare.
+	* maint.c (struct cmd_stats): Remove.
+	(~scoped_command_stats): Rename from report_command_stats.  Now a
+	destructor.
+	(scoped_command_stats): Rename from make_command_stats_cleanup.
+	Now a constructor.
+	* main.c (captured_main): Use scoped_command_stats.
+	* event-top.c (command_handler): Use scoped_command_stats.
+
+2016-09-26  Tom Tromey  <tom@tromey.com>
+
 	* mi/mi-main.c (mi_cmd_data_read_memory): Use std::vector.  Remove
 	some cleanups.
 
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 9b0ccbc..c452501 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -562,13 +562,12 @@ void
 command_handler (char *command)
 {
   struct ui *ui = current_ui;
-  struct cleanup *stat_chain;
   char *c;
 
   if (ui->instream == ui->stdin_stream)
     reinitialize_more_filter ();
 
-  stat_chain = make_command_stats_cleanup (1);
+  scoped_command_stats stat_reporter (1);
 
   /* Do not execute commented lines.  */
   for (c = command; *c == ' ' || *c == '\t'; c++)
@@ -580,8 +579,6 @@ command_handler (char *command)
       /* Do any commands attached to breakpoint we stopped at.  */
       bpstat_do_actions ();
     }
-
-  do_cleanups (stat_chain);
 }
 
 /* Append RL, an input line returned by readline or one of its
diff --git a/gdb/main.c b/gdb/main.c
index 2ea9466..f081136 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -486,661 +486,658 @@ captured_main (void *data)
   int save_auto_load;
   struct objfile *objfile;
 
-  struct cleanup *pre_stat_chain;
-
 #ifdef HAVE_SBRK
-  /* Set this before calling make_command_stats_cleanup.  */
+  /* Set this before constructing scoped_command_stats.  */
   lim_at_start = (char *) sbrk (0);
 #endif
 
-  pre_stat_chain = make_command_stats_cleanup (0);
+  {
+    scoped_command_stats stat_reporter (0);
 
 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
-  setlocale (LC_MESSAGES, "");
+    setlocale (LC_MESSAGES, "");
 #endif
 #if defined (HAVE_SETLOCALE)
-  setlocale (LC_CTYPE, "");
+    setlocale (LC_CTYPE, "");
 #endif
 #ifdef ENABLE_NLS
-  bindtextdomain (PACKAGE, LOCALEDIR);
-  textdomain (PACKAGE);
+    bindtextdomain (PACKAGE, LOCALEDIR);
+    textdomain (PACKAGE);
 #endif
 
-  bfd_init ();
-  notice_open_fds ();
-  save_original_signals_state ();
+    bfd_init ();
+    notice_open_fds ();
+    save_original_signals_state ();
 
-  make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
-  dirsize = 1;
-  dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
-  ndir = 0;
+    make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
+    dirsize = 1;
+    dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
+    ndir = 0;
 
-  saved_command_line = (char *) xstrdup ("");
+    saved_command_line = (char *) xstrdup ("");
 
 #ifdef __MINGW32__
-  /* Ensure stderr is unbuffered.  A Cygwin pty or pipe is implemented
-     as a Windows pipe, and Windows buffers on pipes.  */
-  setvbuf (stderr, NULL, _IONBF, BUFSIZ);
+    /* Ensure stderr is unbuffered.  A Cygwin pty or pipe is implemented
+       as a Windows pipe, and Windows buffers on pipes.  */
+    setvbuf (stderr, NULL, _IONBF, BUFSIZ);
 #endif
 
-  main_ui = new_ui (stdin, stdout, stderr);
-  current_ui = main_ui;
+    main_ui = new_ui (stdin, stdout, stderr);
+    current_ui = main_ui;
 
-  gdb_stdtargerr = gdb_stderr;	/* for moment */
-  gdb_stdtargin = gdb_stdin;	/* for moment */
+    gdb_stdtargerr = gdb_stderr;	/* for moment */
+    gdb_stdtargin = gdb_stdin;	/* for moment */
 
 #ifdef __MINGW32__
-  /* On Windows, argv[0] is not necessarily set to absolute form when
-     GDB is found along PATH, without which relocation doesn't work.  */
-  gdb_program_name = windows_get_absolute_argv0 (argv[0]);
+    /* On Windows, argv[0] is not necessarily set to absolute form when
+       GDB is found along PATH, without which relocation doesn't work.  */
+    gdb_program_name = windows_get_absolute_argv0 (argv[0]);
 #else
-  gdb_program_name = xstrdup (argv[0]);
+    gdb_program_name = xstrdup (argv[0]);
 #endif
 
-  /* Prefix warning messages with the command name.  */
-  warning_pre_print = xstrprintf ("%s: warning: ", gdb_program_name);
+    /* Prefix warning messages with the command name.  */
+    warning_pre_print = xstrprintf ("%s: warning: ", gdb_program_name);
 
-  if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
-    perror_warning_with_name (_("error finding working directory"));
+    if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
+      perror_warning_with_name (_("error finding working directory"));
 
-  current_directory = gdb_dirbuf;
+    current_directory = gdb_dirbuf;
 
-  /* Set the sysroot path.  */
-  gdb_sysroot = relocate_gdb_directory (TARGET_SYSTEM_ROOT,
-					TARGET_SYSTEM_ROOT_RELOCATABLE);
+    /* Set the sysroot path.  */
+    gdb_sysroot = relocate_gdb_directory (TARGET_SYSTEM_ROOT,
+					  TARGET_SYSTEM_ROOT_RELOCATABLE);
 
-  if (gdb_sysroot == NULL || *gdb_sysroot == '\0')
-    {
-      xfree (gdb_sysroot);
-      gdb_sysroot = xstrdup (TARGET_SYSROOT_PREFIX);
-    }
+    if (gdb_sysroot == NULL || *gdb_sysroot == '\0')
+      {
+	xfree (gdb_sysroot);
+	gdb_sysroot = xstrdup (TARGET_SYSROOT_PREFIX);
+      }
 
-  debug_file_directory = relocate_gdb_directory (DEBUGDIR,
-						 DEBUGDIR_RELOCATABLE);
+    debug_file_directory = relocate_gdb_directory (DEBUGDIR,
+						   DEBUGDIR_RELOCATABLE);
 
-  gdb_datadir = relocate_gdb_directory (GDB_DATADIR,
-					GDB_DATADIR_RELOCATABLE);
+    gdb_datadir = relocate_gdb_directory (GDB_DATADIR,
+					  GDB_DATADIR_RELOCATABLE);
 
 #ifdef WITH_PYTHON_PATH
-  {
-    /* For later use in helping Python find itself.  */
-    char *tmp = concat (WITH_PYTHON_PATH, SLASH_STRING, "lib", (char *) NULL);
+    {
+      /* For later use in helping Python find itself.  */
+      char *tmp = concat (WITH_PYTHON_PATH, SLASH_STRING, "lib", (char *) NULL);
 
-    python_libdir = relocate_gdb_directory (tmp, PYTHON_PATH_RELOCATABLE);
-    xfree (tmp);
-  }
+      python_libdir = relocate_gdb_directory (tmp, PYTHON_PATH_RELOCATABLE);
+      xfree (tmp);
+    }
 #endif
 
 #ifdef RELOC_SRCDIR
-  add_substitute_path_rule (RELOC_SRCDIR,
-			    make_relative_prefix (gdb_program_name, BINDIR,
-						  RELOC_SRCDIR));
+    add_substitute_path_rule (RELOC_SRCDIR,
+			      make_relative_prefix (gdb_program_name, BINDIR,
+						    RELOC_SRCDIR));
 #endif
 
-  /* There will always be an interpreter.  Either the one passed into
-     this captured main, or one specified by the user at start up, or
-     the console.  Initialize the interpreter to the one requested by 
-     the application.  */
-  interpreter_p = xstrdup (context->interpreter_p);
+    /* There will always be an interpreter.  Either the one passed into
+       this captured main, or one specified by the user at start up, or
+       the console.  Initialize the interpreter to the one requested by 
+       the application.  */
+    interpreter_p = xstrdup (context->interpreter_p);
 
-  /* Parse arguments and options.  */
-  {
-    int c;
-    /* When var field is 0, use flag field to record the equivalent
-       short option (or arbitrary numbers starting at 10 for those
-       with no equivalent).  */
-    enum {
-      OPT_SE = 10,
-      OPT_CD,
-      OPT_ANNOTATE,
-      OPT_STATISTICS,
-      OPT_TUI,
-      OPT_NOWINDOWS,
-      OPT_WINDOWS,
-      OPT_IX,
-      OPT_IEX
-    };
-    static struct option long_options[] =
+    /* Parse arguments and options.  */
     {
-      {"tui", no_argument, 0, OPT_TUI},
-      {"dbx", no_argument, &dbx_commands, 1},
-      {"readnow", no_argument, &readnow_symbol_files, 1},
-      {"r", no_argument, &readnow_symbol_files, 1},
-      {"quiet", no_argument, &quiet, 1},
-      {"q", no_argument, &quiet, 1},
-      {"silent", no_argument, &quiet, 1},
-      {"nh", no_argument, &inhibit_home_gdbinit, 1},
-      {"nx", no_argument, &inhibit_gdbinit, 1},
-      {"n", no_argument, &inhibit_gdbinit, 1},
-      {"batch-silent", no_argument, 0, 'B'},
-      {"batch", no_argument, &batch_flag, 1},
-
-    /* This is a synonym for "--annotate=1".  --annotate is now
-       preferred, but keep this here for a long time because people
-       will be running emacses which use --fullname.  */
-      {"fullname", no_argument, 0, 'f'},
-      {"f", no_argument, 0, 'f'},
-
-      {"annotate", required_argument, 0, OPT_ANNOTATE},
-      {"help", no_argument, &print_help, 1},
-      {"se", required_argument, 0, OPT_SE},
-      {"symbols", required_argument, 0, 's'},
-      {"s", required_argument, 0, 's'},
-      {"exec", required_argument, 0, 'e'},
-      {"e", required_argument, 0, 'e'},
-      {"core", required_argument, 0, 'c'},
-      {"c", required_argument, 0, 'c'},
-      {"pid", required_argument, 0, 'p'},
-      {"p", required_argument, 0, 'p'},
-      {"command", required_argument, 0, 'x'},
-      {"eval-command", required_argument, 0, 'X'},
-      {"version", no_argument, &print_version, 1},
-      {"configuration", no_argument, &print_configuration, 1},
-      {"x", required_argument, 0, 'x'},
-      {"ex", required_argument, 0, 'X'},
-      {"init-command", required_argument, 0, OPT_IX},
-      {"init-eval-command", required_argument, 0, OPT_IEX},
-      {"ix", required_argument, 0, OPT_IX},
-      {"iex", required_argument, 0, OPT_IEX},
+      int c;
+      /* When var field is 0, use flag field to record the equivalent
+	 short option (or arbitrary numbers starting at 10 for those
+	 with no equivalent).  */
+      enum {
+	OPT_SE = 10,
+	OPT_CD,
+	OPT_ANNOTATE,
+	OPT_STATISTICS,
+	OPT_TUI,
+	OPT_NOWINDOWS,
+	OPT_WINDOWS,
+	OPT_IX,
+	OPT_IEX
+      };
+      static struct option long_options[] =
+	{
+	  {"tui", no_argument, 0, OPT_TUI},
+	  {"dbx", no_argument, &dbx_commands, 1},
+	  {"readnow", no_argument, &readnow_symbol_files, 1},
+	  {"r", no_argument, &readnow_symbol_files, 1},
+	  {"quiet", no_argument, &quiet, 1},
+	  {"q", no_argument, &quiet, 1},
+	  {"silent", no_argument, &quiet, 1},
+	  {"nh", no_argument, &inhibit_home_gdbinit, 1},
+	  {"nx", no_argument, &inhibit_gdbinit, 1},
+	  {"n", no_argument, &inhibit_gdbinit, 1},
+	  {"batch-silent", no_argument, 0, 'B'},
+	  {"batch", no_argument, &batch_flag, 1},
+
+	  /* This is a synonym for "--annotate=1".  --annotate is now
+	     preferred, but keep this here for a long time because people
+	     will be running emacses which use --fullname.  */
+	  {"fullname", no_argument, 0, 'f'},
+	  {"f", no_argument, 0, 'f'},
+
+	  {"annotate", required_argument, 0, OPT_ANNOTATE},
+	  {"help", no_argument, &print_help, 1},
+	  {"se", required_argument, 0, OPT_SE},
+	  {"symbols", required_argument, 0, 's'},
+	  {"s", required_argument, 0, 's'},
+	  {"exec", required_argument, 0, 'e'},
+	  {"e", required_argument, 0, 'e'},
+	  {"core", required_argument, 0, 'c'},
+	  {"c", required_argument, 0, 'c'},
+	  {"pid", required_argument, 0, 'p'},
+	  {"p", required_argument, 0, 'p'},
+	  {"command", required_argument, 0, 'x'},
+	  {"eval-command", required_argument, 0, 'X'},
+	  {"version", no_argument, &print_version, 1},
+	  {"configuration", no_argument, &print_configuration, 1},
+	  {"x", required_argument, 0, 'x'},
+	  {"ex", required_argument, 0, 'X'},
+	  {"init-command", required_argument, 0, OPT_IX},
+	  {"init-eval-command", required_argument, 0, OPT_IEX},
+	  {"ix", required_argument, 0, OPT_IX},
+	  {"iex", required_argument, 0, OPT_IEX},
 #ifdef GDBTK
-      {"tclcommand", required_argument, 0, 'z'},
-      {"enable-external-editor", no_argument, 0, 'y'},
-      {"editor-command", required_argument, 0, 'w'},
+	  {"tclcommand", required_argument, 0, 'z'},
+	  {"enable-external-editor", no_argument, 0, 'y'},
+	  {"editor-command", required_argument, 0, 'w'},
 #endif
-      {"ui", required_argument, 0, 'i'},
-      {"interpreter", required_argument, 0, 'i'},
-      {"i", required_argument, 0, 'i'},
-      {"directory", required_argument, 0, 'd'},
-      {"d", required_argument, 0, 'd'},
-      {"data-directory", required_argument, 0, 'D'},
-      {"D", required_argument, 0, 'D'},
-      {"cd", required_argument, 0, OPT_CD},
-      {"tty", required_argument, 0, 't'},
-      {"baud", required_argument, 0, 'b'},
-      {"b", required_argument, 0, 'b'},
-      {"nw", no_argument, NULL, OPT_NOWINDOWS},
-      {"nowindows", no_argument, NULL, OPT_NOWINDOWS},
-      {"w", no_argument, NULL, OPT_WINDOWS},
-      {"windows", no_argument, NULL, OPT_WINDOWS},
-      {"statistics", no_argument, 0, OPT_STATISTICS},
-      {"write", no_argument, &write_files, 1},
-      {"args", no_argument, &set_args, 1},
-      {"l", required_argument, 0, 'l'},
-      {"return-child-result", no_argument, &return_child_result, 1},
-      {0, no_argument, 0, 0}
-    };
-
-    while (1)
-      {
-	int option_index;
+	  {"ui", required_argument, 0, 'i'},
+	  {"interpreter", required_argument, 0, 'i'},
+	  {"i", required_argument, 0, 'i'},
+	  {"directory", required_argument, 0, 'd'},
+	  {"d", required_argument, 0, 'd'},
+	  {"data-directory", required_argument, 0, 'D'},
+	  {"D", required_argument, 0, 'D'},
+	  {"cd", required_argument, 0, OPT_CD},
+	  {"tty", required_argument, 0, 't'},
+	  {"baud", required_argument, 0, 'b'},
+	  {"b", required_argument, 0, 'b'},
+	  {"nw", no_argument, NULL, OPT_NOWINDOWS},
+	  {"nowindows", no_argument, NULL, OPT_NOWINDOWS},
+	  {"w", no_argument, NULL, OPT_WINDOWS},
+	  {"windows", no_argument, NULL, OPT_WINDOWS},
+	  {"statistics", no_argument, 0, OPT_STATISTICS},
+	  {"write", no_argument, &write_files, 1},
+	  {"args", no_argument, &set_args, 1},
+	  {"l", required_argument, 0, 'l'},
+	  {"return-child-result", no_argument, &return_child_result, 1},
+	  {0, no_argument, 0, 0}
+	};
+
+      while (1)
+	{
+	  int option_index;
 
-	c = getopt_long_only (argc, argv, "",
-			      long_options, &option_index);
-	if (c == EOF || set_args)
-	  break;
+	  c = getopt_long_only (argc, argv, "",
+				long_options, &option_index);
+	  if (c == EOF || set_args)
+	    break;
 
-	/* Long option that takes an argument.  */
-	if (c == 0 && long_options[option_index].flag == 0)
-	  c = long_options[option_index].val;
+	  /* Long option that takes an argument.  */
+	  if (c == 0 && long_options[option_index].flag == 0)
+	    c = long_options[option_index].val;
 
-	switch (c)
-	  {
-	  case 0:
-	    /* Long option that just sets a flag.  */
-	    break;
-	  case OPT_SE:
-	    symarg = optarg;
-	    execarg = optarg;
-	    break;
-	  case OPT_CD:
-	    cdarg = optarg;
-	    break;
-	  case OPT_ANNOTATE:
-	    /* FIXME: what if the syntax is wrong (e.g. not digits)?  */
-	    annotation_level = atoi (optarg);
-	    break;
-	  case OPT_STATISTICS:
-	    /* Enable the display of both time and space usage.  */
-	    set_per_command_time (1);
-	    set_per_command_space (1);
-	    break;
-	  case OPT_TUI:
-	    /* --tui is equivalent to -i=tui.  */
+	  switch (c)
+	    {
+	    case 0:
+	      /* Long option that just sets a flag.  */
+	      break;
+	    case OPT_SE:
+	      symarg = optarg;
+	      execarg = optarg;
+	      break;
+	    case OPT_CD:
+	      cdarg = optarg;
+	      break;
+	    case OPT_ANNOTATE:
+	      /* FIXME: what if the syntax is wrong (e.g. not digits)?  */
+	      annotation_level = atoi (optarg);
+	      break;
+	    case OPT_STATISTICS:
+	      /* Enable the display of both time and space usage.  */
+	      set_per_command_time (1);
+	      set_per_command_space (1);
+	      break;
+	    case OPT_TUI:
+	      /* --tui is equivalent to -i=tui.  */
 #ifdef TUI
-	    xfree (interpreter_p);
-	    interpreter_p = xstrdup (INTERP_TUI);
+	      xfree (interpreter_p);
+	      interpreter_p = xstrdup (INTERP_TUI);
 #else
-	    error (_("%s: TUI mode is not supported"), gdb_program_name);
+	      error (_("%s: TUI mode is not supported"), gdb_program_name);
 #endif
-	    break;
-	  case OPT_WINDOWS:
-	    /* FIXME: cagney/2003-03-01: Not sure if this option is
-               actually useful, and if it is, what it should do.  */
+	      break;
+	    case OPT_WINDOWS:
+	      /* FIXME: cagney/2003-03-01: Not sure if this option is
+		 actually useful, and if it is, what it should do.  */
 #ifdef GDBTK
-	    /* --windows is equivalent to -i=insight.  */
-	    xfree (interpreter_p);
-	    interpreter_p = xstrdup (INTERP_INSIGHT);
+	      /* --windows is equivalent to -i=insight.  */
+	      xfree (interpreter_p);
+	      interpreter_p = xstrdup (INTERP_INSIGHT);
 #endif
-	    break;
-	  case OPT_NOWINDOWS:
-	    /* -nw is equivalent to -i=console.  */
-	    xfree (interpreter_p);
-	    interpreter_p = xstrdup (INTERP_CONSOLE);
-	    break;
-	  case 'f':
-	    annotation_level = 1;
-	    break;
-	  case 's':
-	    symarg = optarg;
-	    break;
-	  case 'e':
-	    execarg = optarg;
-	    break;
-	  case 'c':
-	    corearg = optarg;
-	    break;
-	  case 'p':
-	    pidarg = optarg;
-	    break;
-	  case 'x':
-	    {
-	      struct cmdarg cmdarg = { CMDARG_FILE, optarg };
+	      break;
+	    case OPT_NOWINDOWS:
+	      /* -nw is equivalent to -i=console.  */
+	      xfree (interpreter_p);
+	      interpreter_p = xstrdup (INTERP_CONSOLE);
+	      break;
+	    case 'f':
+	      annotation_level = 1;
+	      break;
+	    case 's':
+	      symarg = optarg;
+	      break;
+	    case 'e':
+	      execarg = optarg;
+	      break;
+	    case 'c':
+	      corearg = optarg;
+	      break;
+	    case 'p':
+	      pidarg = optarg;
+	      break;
+	    case 'x':
+	      {
+		struct cmdarg cmdarg = { CMDARG_FILE, optarg };
 
-	      VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
-	    }
-	    break;
-	  case 'X':
-	    {
-	      struct cmdarg cmdarg = { CMDARG_COMMAND, optarg };
+		VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+	      }
+	      break;
+	    case 'X':
+	      {
+		struct cmdarg cmdarg = { CMDARG_COMMAND, optarg };
 
-	      VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
-	    }
-	    break;
-	  case OPT_IX:
-	    {
-	      struct cmdarg cmdarg = { CMDARG_INIT_FILE, optarg };
+		VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+	      }
+	      break;
+	    case OPT_IX:
+	      {
+		struct cmdarg cmdarg = { CMDARG_INIT_FILE, optarg };
 
-	      VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
-	    }
-	    break;
-	  case OPT_IEX:
-	    {
-	      struct cmdarg cmdarg = { CMDARG_INIT_COMMAND, optarg };
+		VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+	      }
+	      break;
+	    case OPT_IEX:
+	      {
+		struct cmdarg cmdarg = { CMDARG_INIT_COMMAND, optarg };
 
-	      VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
-	    }
-	    break;
-	  case 'B':
-	    batch_flag = batch_silent = 1;
-	    gdb_stdout = ui_file_new();
-	    break;
-	  case 'D':
-	    if (optarg[0] == '\0')
-	      error (_("%s: empty path for `--data-directory'"),
-		     gdb_program_name);
-	    set_gdb_data_directory (optarg);
-	    gdb_datadir_provided = 1;
-	    break;
+		VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
+	      }
+	      break;
+	    case 'B':
+	      batch_flag = batch_silent = 1;
+	      gdb_stdout = ui_file_new();
+	      break;
+	    case 'D':
+	      if (optarg[0] == '\0')
+		error (_("%s: empty path for `--data-directory'"),
+		       gdb_program_name);
+	      set_gdb_data_directory (optarg);
+	      gdb_datadir_provided = 1;
+	      break;
 #ifdef GDBTK
-	  case 'z':
-	    {
-	      extern int gdbtk_test (char *);
+	    case 'z':
+	      {
+		extern int gdbtk_test (char *);
 
-	      if (!gdbtk_test (optarg))
-		error (_("%s: unable to load tclcommand file \"%s\""),
-		       gdb_program_name, optarg);
+		if (!gdbtk_test (optarg))
+		  error (_("%s: unable to load tclcommand file \"%s\""),
+			 gdb_program_name, optarg);
+		break;
+	      }
+	    case 'y':
+	      /* Backwards compatibility only.  */
 	      break;
-	    }
-	  case 'y':
-	    /* Backwards compatibility only.  */
-	    break;
-	  case 'w':
-	    {
-	      /* Set the external editor commands when gdb is farming out files
-		 to be edited by another program.  */
-	      extern char *external_editor_command;
+	    case 'w':
+	      {
+		/* Set the external editor commands when gdb is farming out files
+		   to be edited by another program.  */
+		extern char *external_editor_command;
 
-	      external_editor_command = xstrdup (optarg);
-	      break;
-	    }
+		external_editor_command = xstrdup (optarg);
+		break;
+	      }
 #endif /* GDBTK */
-	  case 'i':
-	    xfree (interpreter_p);
-	    interpreter_p = xstrdup (optarg);
-	    break;
-	  case 'd':
-	    dirarg[ndir++] = optarg;
-	    if (ndir >= dirsize)
+	    case 'i':
+	      xfree (interpreter_p);
+	      interpreter_p = xstrdup (optarg);
+	      break;
+	    case 'd':
+	      dirarg[ndir++] = optarg;
+	      if (ndir >= dirsize)
+		{
+		  dirsize *= 2;
+		  dirarg = (char **) xrealloc ((char *) dirarg,
+					       dirsize * sizeof (*dirarg));
+		}
+	      break;
+	    case 't':
+	      ttyarg = optarg;
+	      break;
+	    case 'q':
+	      quiet = 1;
+	      break;
+	    case 'b':
 	      {
-		dirsize *= 2;
-		dirarg = (char **) xrealloc ((char *) dirarg,
-					     dirsize * sizeof (*dirarg));
+		int i;
+		char *p;
+
+		i = strtol (optarg, &p, 0);
+		if (i == 0 && p == optarg)
+		  warning (_("could not set baud rate to `%s'."),
+			   optarg);
+		else
+		  baud_rate = i;
 	      }
-	    break;
-	  case 't':
-	    ttyarg = optarg;
-	    break;
-	  case 'q':
-	    quiet = 1;
-	    break;
-	  case 'b':
-	    {
-	      int i;
-	      char *p;
-
-	      i = strtol (optarg, &p, 0);
-	      if (i == 0 && p == optarg)
-		warning (_("could not set baud rate to `%s'."),
-			 optarg);
-	      else
-		baud_rate = i;
-	    }
-            break;
-	  case 'l':
-	    {
-	      int i;
-	      char *p;
+	      break;
+	    case 'l':
+	      {
+		int i;
+		char *p;
+
+		i = strtol (optarg, &p, 0);
+		if (i == 0 && p == optarg)
+		  warning (_("could not set timeout limit to `%s'."),
+			   optarg);
+		else
+		  remote_timeout = i;
+	      }
+	      break;
 
-	      i = strtol (optarg, &p, 0);
-	      if (i == 0 && p == optarg)
-		warning (_("could not set timeout limit to `%s'."),
-			 optarg);
-	      else
-		remote_timeout = i;
+	    case '?':
+	      error (_("Use `%s --help' for a complete list of options."),
+		     gdb_program_name);
 	    }
-	    break;
-
-	  case '?':
-	    error (_("Use `%s --help' for a complete list of options."),
-		   gdb_program_name);
-	  }
-      }
+	}
 
-    if (batch_flag)
-      quiet = 1;
-  }
+      if (batch_flag)
+	quiet = 1;
+    }
 
-  /* Try to set up an alternate signal stack for SIGSEGV handlers.  */
-  setup_alternate_signal_stack ();
+    /* Try to set up an alternate signal stack for SIGSEGV handlers.  */
+    setup_alternate_signal_stack ();
 
-  /* Initialize all files.  */
-  gdb_init (gdb_program_name);
+    /* Initialize all files.  */
+    gdb_init (gdb_program_name);
 
-  /* Now that gdb_init has created the initial inferior, we're in
-     position to set args for that inferior.  */
-  if (set_args)
-    {
-      /* The remaining options are the command-line options for the
-	 inferior.  The first one is the sym/exec file, and the rest
-	 are arguments.  */
-      if (optind >= argc)
-	error (_("%s: `--args' specified but no program specified"),
-	       gdb_program_name);
-
-      symarg = argv[optind];
-      execarg = argv[optind];
-      ++optind;
-      set_inferior_args_vector (argc - optind, &argv[optind]);
-    }
-  else
-    {
-      /* OK, that's all the options.  */
+    /* Now that gdb_init has created the initial inferior, we're in
+       position to set args for that inferior.  */
+    if (set_args)
+      {
+	/* The remaining options are the command-line options for the
+	   inferior.  The first one is the sym/exec file, and the rest
+	   are arguments.  */
+	if (optind >= argc)
+	  error (_("%s: `--args' specified but no program specified"),
+		 gdb_program_name);
+
+	symarg = argv[optind];
+	execarg = argv[optind];
+	++optind;
+	set_inferior_args_vector (argc - optind, &argv[optind]);
+      }
+    else
+      {
+	/* OK, that's all the options.  */
 
-      /* The first argument, if specified, is the name of the
-	 executable.  */
-      if (optind < argc)
-	{
-	  symarg = argv[optind];
-	  execarg = argv[optind];
-	  optind++;
-	}
+	/* The first argument, if specified, is the name of the
+	   executable.  */
+	if (optind < argc)
+	  {
+	    symarg = argv[optind];
+	    execarg = argv[optind];
+	    optind++;
+	  }
 
-      /* If the user hasn't already specified a PID or the name of a
-	 core file, then a second optional argument is allowed.  If
-	 present, this argument should be interpreted as either a
-	 PID or a core file, whichever works.  */
-      if (pidarg == NULL && corearg == NULL && optind < argc)
-	{
-	  pid_or_core_arg = argv[optind];
-	  optind++;
-	}
+	/* If the user hasn't already specified a PID or the name of a
+	   core file, then a second optional argument is allowed.  If
+	   present, this argument should be interpreted as either a
+	   PID or a core file, whichever works.  */
+	if (pidarg == NULL && corearg == NULL && optind < argc)
+	  {
+	    pid_or_core_arg = argv[optind];
+	    optind++;
+	  }
 
-      /* Any argument left on the command line is unexpected and
-	 will be ignored.  Inform the user.  */
-      if (optind < argc)
-	fprintf_unfiltered (gdb_stderr,
-			    _("Excess command line "
-			      "arguments ignored. (%s%s)\n"),
-			    argv[optind],
-			    (optind == argc - 1) ? "" : " ...");
-    }
+	/* Any argument left on the command line is unexpected and
+	   will be ignored.  Inform the user.  */
+	if (optind < argc)
+	  fprintf_unfiltered (gdb_stderr,
+			      _("Excess command line "
+				"arguments ignored. (%s%s)\n"),
+			      argv[optind],
+			      (optind == argc - 1) ? "" : " ...");
+      }
 
-  /* Lookup gdbinit files.  Note that the gdbinit file name may be
-     overriden during file initialization, so get_init_files should be
-     called after gdb_init.  */
-  get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
+    /* Lookup gdbinit files.  Note that the gdbinit file name may be
+       overriden during file initialization, so get_init_files should be
+       called after gdb_init.  */
+    get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
 
-  /* Do these (and anything which might call wrap_here or *_filtered)
-     after initialize_all_files() but before the interpreter has been
-     installed.  Otherwize the help/version messages will be eaten by
-     the interpreter's output handler.  */
+    /* Do these (and anything which might call wrap_here or *_filtered)
+       after initialize_all_files() but before the interpreter has been
+       installed.  Otherwize the help/version messages will be eaten by
+       the interpreter's output handler.  */
 
-  if (print_version)
-    {
-      print_gdb_version (gdb_stdout);
-      wrap_here ("");
-      printf_filtered ("\n");
-      exit (0);
-    }
+    if (print_version)
+      {
+	print_gdb_version (gdb_stdout);
+	wrap_here ("");
+	printf_filtered ("\n");
+	exit (0);
+      }
 
-  if (print_help)
-    {
-      print_gdb_help (gdb_stdout);
-      fputs_unfiltered ("\n", gdb_stdout);
-      exit (0);
-    }
+    if (print_help)
+      {
+	print_gdb_help (gdb_stdout);
+	fputs_unfiltered ("\n", gdb_stdout);
+	exit (0);
+      }
 
-  if (print_configuration)
-    {
-      print_gdb_configuration (gdb_stdout);
-      wrap_here ("");
-      printf_filtered ("\n");
-      exit (0);
-    }
+    if (print_configuration)
+      {
+	print_gdb_configuration (gdb_stdout);
+	wrap_here ("");
+	printf_filtered ("\n");
+	exit (0);
+      }
 
-  /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
-     GDB retain the old MI1 interpreter startup behavior.  Output the
-     copyright message before the interpreter is installed.  That way
-     it isn't encapsulated in MI output.  */
-  if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
-    {
-      /* Print all the junk at the top, with trailing "..." if we are
-         about to read a symbol file (possibly slowly).  */
-      print_gdb_version (gdb_stdout);
-      if (symarg)
-	printf_filtered ("..");
-      wrap_here ("");
-      printf_filtered ("\n");
-      gdb_flush (gdb_stdout);	/* Force to screen during slow
+    /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
+       GDB retain the old MI1 interpreter startup behavior.  Output the
+       copyright message before the interpreter is installed.  That way
+       it isn't encapsulated in MI output.  */
+    if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
+      {
+	/* Print all the junk at the top, with trailing "..." if we are
+	   about to read a symbol file (possibly slowly).  */
+	print_gdb_version (gdb_stdout);
+	if (symarg)
+	  printf_filtered ("..");
+	wrap_here ("");
+	printf_filtered ("\n");
+	gdb_flush (gdb_stdout);	/* Force to screen during slow
 				   operations.  */
-    }
+      }
 
-  /* Install the default UI.  All the interpreters should have had a
-     look at things by now.  Initialize the default interpreter.  */
-  set_top_level_interpreter (interpreter_p);
+    /* Install the default UI.  All the interpreters should have had a
+       look at things by now.  Initialize the default interpreter.  */
+    set_top_level_interpreter (interpreter_p);
 
-  /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
-     GDB retain the old MI1 interpreter startup behavior.  Output the
-     copyright message after the interpreter is installed when it is
-     any sane interpreter.  */
-  if (!quiet && !current_interp_named_p (INTERP_MI1))
-    {
-      /* Print all the junk at the top, with trailing "..." if we are
-         about to read a symbol file (possibly slowly).  */
-      print_gdb_version (gdb_stdout);
-      if (symarg)
-	printf_filtered ("..");
-      wrap_here ("");
-      printf_filtered ("\n");
-      gdb_flush (gdb_stdout);	/* Force to screen during slow
+    /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
+       GDB retain the old MI1 interpreter startup behavior.  Output the
+       copyright message after the interpreter is installed when it is
+       any sane interpreter.  */
+    if (!quiet && !current_interp_named_p (INTERP_MI1))
+      {
+	/* Print all the junk at the top, with trailing "..." if we are
+	   about to read a symbol file (possibly slowly).  */
+	print_gdb_version (gdb_stdout);
+	if (symarg)
+	  printf_filtered ("..");
+	wrap_here ("");
+	printf_filtered ("\n");
+	gdb_flush (gdb_stdout);	/* Force to screen during slow
 				   operations.  */
-    }
+      }
 
-  /* Set off error and warning messages with a blank line.  */
-  xfree (warning_pre_print);
-  warning_pre_print = _("\nwarning: ");
+    /* Set off error and warning messages with a blank line.  */
+    xfree (warning_pre_print);
+    warning_pre_print = _("\nwarning: ");
 
-  /* Read and execute the system-wide gdbinit file, if it exists.
-     This is done *before* all the command line arguments are
-     processed; it sets global parameters, which are independent of
-     what file you are debugging or what directory you are in.  */
-  if (system_gdbinit && !inhibit_gdbinit)
-    catch_command_errors_const (source_script, system_gdbinit, 0);
+    /* Read and execute the system-wide gdbinit file, if it exists.
+       This is done *before* all the command line arguments are
+       processed; it sets global parameters, which are independent of
+       what file you are debugging or what directory you are in.  */
+    if (system_gdbinit && !inhibit_gdbinit)
+      catch_command_errors_const (source_script, system_gdbinit, 0);
 
-  /* Read and execute $HOME/.gdbinit file, if it exists.  This is done
+    /* Read and execute $HOME/.gdbinit file, if it exists.  This is done
      *before* all the command line arguments are processed; it sets
      global parameters, which are independent of what file you are
      debugging or what directory you are in.  */
 
-  if (home_gdbinit && !inhibit_gdbinit && !inhibit_home_gdbinit)
-    catch_command_errors_const (source_script, home_gdbinit, 0);
-
-  /* Process '-ix' and '-iex' options early.  */
-  for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
-    switch (cmdarg_p->type)
-    {
-      case CMDARG_INIT_FILE:
-        catch_command_errors_const (source_script, cmdarg_p->string,
-				    !batch_flag);
-	break;
-      case CMDARG_INIT_COMMAND:
-        catch_command_errors (execute_command, cmdarg_p->string,
-			      !batch_flag);
-	break;
-    }
+    if (home_gdbinit && !inhibit_gdbinit && !inhibit_home_gdbinit)
+      catch_command_errors_const (source_script, home_gdbinit, 0);
 
-  /* Now perform all the actions indicated by the arguments.  */
-  if (cdarg != NULL)
-    {
-      catch_command_errors (cd_command, cdarg, 0);
-    }
+    /* Process '-ix' and '-iex' options early.  */
+    for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
+      switch (cmdarg_p->type)
+	{
+	case CMDARG_INIT_FILE:
+	  catch_command_errors_const (source_script, cmdarg_p->string,
+				      !batch_flag);
+	  break;
+	case CMDARG_INIT_COMMAND:
+	  catch_command_errors (execute_command, cmdarg_p->string,
+				!batch_flag);
+	  break;
+	}
 
-  for (i = 0; i < ndir; i++)
-    catch_command_errors (directory_switch, dirarg[i], 0);
-  xfree (dirarg);
+    /* Now perform all the actions indicated by the arguments.  */
+    if (cdarg != NULL)
+      {
+	catch_command_errors (cd_command, cdarg, 0);
+      }
 
-  /* Skip auto-loading section-specified scripts until we've sourced
-     local_gdbinit (which is often used to augment the source search
-     path).  */
-  save_auto_load = global_auto_load;
-  global_auto_load = 0;
+    for (i = 0; i < ndir; i++)
+      catch_command_errors (directory_switch, dirarg[i], 0);
+    xfree (dirarg);
 
-  if (execarg != NULL
-      && symarg != NULL
-      && strcmp (execarg, symarg) == 0)
-    {
-      /* The exec file and the symbol-file are the same.  If we can't
-         open it, better only print one error message.
-         catch_command_errors returns non-zero on success!  */
-      if (catch_command_errors_const (exec_file_attach, execarg,
-				      !batch_flag))
-	catch_command_errors_const (symbol_file_add_main, symarg,
-				    !batch_flag);
-    }
-  else
-    {
-      if (execarg != NULL)
-	catch_command_errors_const (exec_file_attach, execarg,
-				    !batch_flag);
-      if (symarg != NULL)
-	catch_command_errors_const (symbol_file_add_main, symarg,
-				    !batch_flag);
-    }
+    /* Skip auto-loading section-specified scripts until we've sourced
+       local_gdbinit (which is often used to augment the source search
+       path).  */
+    save_auto_load = global_auto_load;
+    global_auto_load = 0;
 
-  if (corearg && pidarg)
-    error (_("Can't attach to process and specify "
-	     "a core file at the same time."));
+    if (execarg != NULL
+	&& symarg != NULL
+	&& strcmp (execarg, symarg) == 0)
+      {
+	/* The exec file and the symbol-file are the same.  If we can't
+	   open it, better only print one error message.
+	   catch_command_errors returns non-zero on success!  */
+	if (catch_command_errors_const (exec_file_attach, execarg,
+					!batch_flag))
+	  catch_command_errors_const (symbol_file_add_main, symarg,
+				      !batch_flag);
+      }
+    else
+      {
+	if (execarg != NULL)
+	  catch_command_errors_const (exec_file_attach, execarg,
+				      !batch_flag);
+	if (symarg != NULL)
+	  catch_command_errors_const (symbol_file_add_main, symarg,
+				      !batch_flag);
+      }
 
-  if (corearg != NULL)
-    catch_command_errors (core_file_command, corearg, !batch_flag);
-  else if (pidarg != NULL)
-    catch_command_errors (attach_command, pidarg, !batch_flag);
-  else if (pid_or_core_arg)
-    {
-      /* The user specified 'gdb program pid' or gdb program core'.
-	 If pid_or_core_arg's first character is a digit, try attach
-	 first and then corefile.  Otherwise try just corefile.  */
+    if (corearg && pidarg)
+      error (_("Can't attach to process and specify "
+	       "a core file at the same time."));
 
-      if (isdigit (pid_or_core_arg[0]))
-	{
-	  if (catch_command_errors (attach_command, pid_or_core_arg,
-				    !batch_flag) == 0)
-	    catch_command_errors (core_file_command, pid_or_core_arg,
-				  !batch_flag);
-	}
-      else /* Can't be a pid, better be a corefile.  */
-	catch_command_errors (core_file_command, pid_or_core_arg,
-			      !batch_flag);
-    }
+    if (corearg != NULL)
+      catch_command_errors (core_file_command, corearg, !batch_flag);
+    else if (pidarg != NULL)
+      catch_command_errors (attach_command, pidarg, !batch_flag);
+    else if (pid_or_core_arg)
+      {
+	/* The user specified 'gdb program pid' or gdb program core'.
+	   If pid_or_core_arg's first character is a digit, try attach
+	   first and then corefile.  Otherwise try just corefile.  */
 
-  if (ttyarg != NULL)
-    set_inferior_io_terminal (ttyarg);
+	if (isdigit (pid_or_core_arg[0]))
+	  {
+	    if (catch_command_errors (attach_command, pid_or_core_arg,
+				      !batch_flag) == 0)
+	      catch_command_errors (core_file_command, pid_or_core_arg,
+				    !batch_flag);
+	  }
+	else /* Can't be a pid, better be a corefile.  */
+	  catch_command_errors (core_file_command, pid_or_core_arg,
+				!batch_flag);
+      }
 
-  /* Error messages should no longer be distinguished with extra output.  */
-  warning_pre_print = _("warning: ");
+    if (ttyarg != NULL)
+      set_inferior_io_terminal (ttyarg);
 
-  /* Read the .gdbinit file in the current directory, *if* it isn't
-     the same as the $HOME/.gdbinit file (it should exist, also).  */
-  if (local_gdbinit)
-    {
-      auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit);
+    /* Error messages should no longer be distinguished with extra output.  */
+    warning_pre_print = _("warning: ");
 
-      if (!inhibit_gdbinit && auto_load_local_gdbinit
-	  && file_is_auto_load_safe (local_gdbinit,
-				     _("auto-load: Loading .gdbinit "
-				       "file \"%s\".\n"),
-				     local_gdbinit))
-	{
-	  auto_load_local_gdbinit_loaded = 1;
+    /* Read the .gdbinit file in the current directory, *if* it isn't
+       the same as the $HOME/.gdbinit file (it should exist, also).  */
+    if (local_gdbinit)
+      {
+	auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit);
 
-	  catch_command_errors_const (source_script, local_gdbinit, 0);
-	}
-    }
+	if (!inhibit_gdbinit && auto_load_local_gdbinit
+	    && file_is_auto_load_safe (local_gdbinit,
+				       _("auto-load: Loading .gdbinit "
+					 "file \"%s\".\n"),
+				       local_gdbinit))
+	  {
+	    auto_load_local_gdbinit_loaded = 1;
 
-  /* Now that all .gdbinit's have been read and all -d options have been
-     processed, we can read any scripts mentioned in SYMARG.
-     We wait until now because it is common to add to the source search
-     path in local_gdbinit.  */
-  global_auto_load = save_auto_load;
-  ALL_OBJFILES (objfile)
-    load_auto_scripts_for_objfile (objfile);
-
-  /* Process '-x' and '-ex' options.  */
-  for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
-    switch (cmdarg_p->type)
-    {
-      case CMDARG_FILE:
-        catch_command_errors_const (source_script, cmdarg_p->string,
-				    !batch_flag);
-	break;
-      case CMDARG_COMMAND:
-        catch_command_errors (execute_command, cmdarg_p->string,
-			      !batch_flag);
-	break;
-    }
+	    catch_command_errors_const (source_script, local_gdbinit, 0);
+	  }
+      }
 
-  /* Read in the old history after all the command files have been
-     read.  */
-  init_history ();
+    /* Now that all .gdbinit's have been read and all -d options have been
+       processed, we can read any scripts mentioned in SYMARG.
+       We wait until now because it is common to add to the source search
+       path in local_gdbinit.  */
+    global_auto_load = save_auto_load;
+    ALL_OBJFILES (objfile)
+      load_auto_scripts_for_objfile (objfile);
+
+    /* Process '-x' and '-ex' options.  */
+    for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
+      switch (cmdarg_p->type)
+	{
+	case CMDARG_FILE:
+	  catch_command_errors_const (source_script, cmdarg_p->string,
+				      !batch_flag);
+	  break;
+	case CMDARG_COMMAND:
+	  catch_command_errors (execute_command, cmdarg_p->string,
+				!batch_flag);
+	  break;
+	}
 
-  if (batch_flag)
-    {
-      /* We have hit the end of the batch file.  */
-      quit_force (NULL, 0);
-    }
+    /* Read in the old history after all the command files have been
+       read.  */
+    init_history ();
 
-  /* Show time and/or space usage.  */
-  do_cleanups (pre_stat_chain);
+    if (batch_flag)
+      {
+	/* We have hit the end of the batch file.  */
+	quit_force (NULL, 0);
+      }
+  }
 
   /* NOTE: cagney/1999-11-07: There is probably no reason for not
      moving this loop and the code found in captured_command_loop()
diff --git a/gdb/maint.c b/gdb/maint.c
index d2c9346..dad13fa 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -752,31 +752,6 @@ static int per_command_symtab;
 static struct cmd_list_element *per_command_setlist;
 static struct cmd_list_element *per_command_showlist;
 
-/* Records a run time and space usage to be used as a base for
-   reporting elapsed time or change in space.  */
-
-struct cmd_stats 
-{
-  /* Zero if the saved time is from the beginning of GDB execution.
-     One if from the beginning of an individual command execution.  */
-  int msg_type;
-  /* Track whether the stat was enabled at the start of the command
-     so that we can avoid printing anything if it gets turned on by
-     the current command.  */
-  int time_enabled : 1;
-  int space_enabled : 1;
-  int symtab_enabled : 1;
-  long start_cpu_time;
-  struct timeval start_wall_time;
-  long start_space;
-  /* Total number of symtabs (over all objfiles).  */
-  int start_nr_symtabs;
-  /* A count of the compunits.  */
-  int start_nr_compunit_symtabs;
-  /* Total number of blocks.  */
-  int start_nr_blocks;
-};
-
 /* Set whether to display time statistics to NEW_VALUE
    (non-zero means true).  */
 
@@ -827,25 +802,32 @@ count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
   *nr_blocks_ptr = nr_blocks;
 }
 
-/* As indicated by display_time and display_space, report GDB's elapsed time
-   and space usage from the base time and space provided in ARG, which
-   must be a pointer to a struct cmd_stat.  This function is intended
-   to be called as a cleanup.  */
+/* As indicated by display_time and display_space, report GDB's
+   elapsed time and space usage from the base time and space recorded
+   in this object.  */
 
-static void
-report_command_stats (void *arg)
+scoped_command_stats::~scoped_command_stats ()
 {
-  struct cmd_stats *start_stats = (struct cmd_stats *) arg;
-  int msg_type = start_stats->msg_type;
+  /* Early exit if we're not reporting any stats.  It can be expensive to
+     compute the pre-command values so don't collect them at all if we're
+     not reporting stats.  Alas this doesn't work in the startup case because
+     we don't know yet whether we will be reporting the stats.  For the
+     startup case collect the data anyway (it should be cheap at this point),
+     and leave it to the reporter to decide whether to print them.  */
+  if (msg_type != 0
+      && !per_command_time
+      && !per_command_space
+      && !per_command_symtab)
+    return;
 
-  if (start_stats->time_enabled && per_command_time)
+  if (this->time_enabled && per_command_time)
     {
-      long cmd_time = get_run_time () - start_stats->start_cpu_time;
+      long cmd_time = get_run_time () - this->start_cpu_time;
       struct timeval now_wall_time, delta_wall_time, wait_time;
 
       gettimeofday (&now_wall_time, NULL);
       timeval_sub (&delta_wall_time,
-		   &now_wall_time, &start_stats->start_wall_time);
+		   &now_wall_time, &this->start_wall_time);
 
       /* Subtract time spend in prompt_for_continue from walltime.  */
       wait_time = get_prompt_for_continue_wait_time ();
@@ -859,13 +841,13 @@ report_command_stats (void *arg)
 			 (long) delta_wall_time.tv_usec);
     }
 
-  if (start_stats->space_enabled && per_command_space)
+  if (this->space_enabled && per_command_space)
     {
 #ifdef HAVE_SBRK
       char *lim = (char *) sbrk (0);
 
       long space_now = lim - lim_at_start;
-      long space_diff = space_now - start_stats->start_space;
+      long space_diff = space_now - this->start_space;
 
       printf_unfiltered (msg_type == 0
 			 ? _("Space used: %ld (%s%ld during startup)\n")
@@ -876,7 +858,7 @@ report_command_stats (void *arg)
 #endif
     }
 
-  if (start_stats->symtab_enabled && per_command_symtab)
+  if (this->symtab_enabled && per_command_symtab)
     {
       int nr_symtabs, nr_compunit_symtabs, nr_blocks;
 
@@ -885,54 +867,32 @@ report_command_stats (void *arg)
 			   " #compunits: %d (+%d),"
 			   " #blocks: %d (+%d)\n"),
 			 nr_symtabs,
-			 nr_symtabs - start_stats->start_nr_symtabs,
+			 nr_symtabs - this->start_nr_symtabs,
 			 nr_compunit_symtabs,
 			 (nr_compunit_symtabs
-			  - start_stats->start_nr_compunit_symtabs),
+			  - this->start_nr_compunit_symtabs),
 			 nr_blocks,
-			 nr_blocks - start_stats->start_nr_blocks);
+			 nr_blocks - this->start_nr_blocks);
     }
 }
 
-/* Create a cleanup that reports time and space used since its creation.
-   MSG_TYPE is zero for gdb startup, otherwise it is one(1) to report
-   data for individual commands.  */
-
-struct cleanup *
-make_command_stats_cleanup (int msg_type)
+scoped_command_stats::scoped_command_stats (int msg_type)
+: msg_type (msg_type)
 {
-  struct cmd_stats *new_stat;
-
-  /* Early exit if we're not reporting any stats.  It can be expensive to
-     compute the pre-command values so don't collect them at all if we're
-     not reporting stats.  Alas this doesn't work in the startup case because
-     we don't know yet whether we will be reporting the stats.  For the
-     startup case collect the data anyway (it should be cheap at this point),
-     and leave it to the reporter to decide whether to print them.  */
-  if (msg_type != 0
-      && !per_command_time
-      && !per_command_space
-      && !per_command_symtab)
-    return make_cleanup (null_cleanup, 0);
-
-  new_stat = XCNEW (struct cmd_stats);
-
-  new_stat->msg_type = msg_type;
-
   if (msg_type == 0 || per_command_space)
     {
 #ifdef HAVE_SBRK
       char *lim = (char *) sbrk (0);
-      new_stat->start_space = lim - lim_at_start;
-      new_stat->space_enabled = 1;
+      this->start_space = lim - lim_at_start;
+      this->space_enabled = 1;
 #endif
     }
 
   if (msg_type == 0 || per_command_time)
     {
-      new_stat->start_cpu_time = get_run_time ();
-      gettimeofday (&new_stat->start_wall_time, NULL);
-      new_stat->time_enabled = 1;
+      this->start_cpu_time = get_run_time ();
+      gettimeofday (&this->start_wall_time, NULL);
+      this->time_enabled = 1;
     }
 
   if (msg_type == 0 || per_command_symtab)
@@ -940,16 +900,14 @@ make_command_stats_cleanup (int msg_type)
       int nr_symtabs, nr_compunit_symtabs, nr_blocks;
 
       count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
-      new_stat->start_nr_symtabs = nr_symtabs;
-      new_stat->start_nr_compunit_symtabs = nr_compunit_symtabs;
-      new_stat->start_nr_blocks = nr_blocks;
-      new_stat->symtab_enabled = 1;
+      this->start_nr_symtabs = nr_symtabs;
+      this->start_nr_compunit_symtabs = nr_compunit_symtabs;
+      this->start_nr_blocks = nr_blocks;
+      this->symtab_enabled = 1;
     }
 
   /* Initalize timer to keep track of how long we waited for the user.  */
   reset_prompt_for_continue_wait_time ();
-
-  return make_cleanup_dtor (report_command_stats, new_stat, xfree);
 }
 
 /* Handle unknown "mt set per-command" arguments.
diff --git a/gdb/maint.h b/gdb/maint.h
index 841e790..f517fa4 100644
--- a/gdb/maint.h
+++ b/gdb/maint.h
@@ -23,9 +23,40 @@ extern void set_per_command_time (int);
 
 extern void set_per_command_space (int);
 
-/* Note: There's no set_per_command_symtab on purpose.
-   Symtab stats aren't yet as useful for --statistics output.  */
-
-extern struct cleanup *make_command_stats_cleanup (int);
+/* Records a run time and space usage to be used as a base for
+   reporting elapsed time or change in space.  */
+
+class scoped_command_stats
+{
+ public:
+
+  scoped_command_stats (int msg_type);
+  ~scoped_command_stats ();
+
+ private:
+
+  // No need for these.  They are intentionally not defined anywhere.
+  scoped_command_stats &operator= (const scoped_command_stats &);
+  scoped_command_stats (const scoped_command_stats &);
+
+  /* Zero if the saved time is from the beginning of GDB execution.
+     One if from the beginning of an individual command execution.  */
+  int msg_type;
+  /* Track whether the stat was enabled at the start of the command
+     so that we can avoid printing anything if it gets turned on by
+     the current command.  */
+  int time_enabled : 1;
+  int space_enabled : 1;
+  int symtab_enabled : 1;
+  long start_cpu_time;
+  struct timeval start_wall_time;
+  long start_space;
+  /* Total number of symtabs (over all objfiles).  */
+  int start_nr_symtabs;
+  /* A count of the compunits.  */
+  int start_nr_compunit_symtabs;
+  /* Total number of blocks.  */
+  int start_nr_blocks;
+};
 
 #endif /* MAINT_H */
