From patchwork Tue Sep 27 04:08:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 16066 Received: (qmail 110407 invoked by alias); 27 Sep 2016 04:52:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 110384 invoked by uid 89); 27 Sep 2016 04:52:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=augment, *tmp, 23, 9, success! X-HELO: gproxy5-pub.mail.unifiedlayer.com Received: from gproxy5-pub.mail.unifiedlayer.com (HELO gproxy5-pub.mail.unifiedlayer.com) (67.222.38.55) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with SMTP; Tue, 27 Sep 2016 04:52:39 +0000 Received: (qmail 10451 invoked by uid 0); 27 Sep 2016 04:52:38 -0000 Received: from unknown (HELO cmgw3) (10.0.90.84) by gproxy5.mail.unifiedlayer.com with SMTP; 27 Sep 2016 04:52:38 -0000 Received: from box522.bluehost.com ([74.220.219.122]) by cmgw3 with id oUsb1t0022f2jeq01UsezV; Mon, 26 Sep 2016 22:52:38 -0600 X-Authority-Analysis: v=2.1 cv=aaryw3Yt c=1 sm=1 tr=0 a=GsOEXm/OWkKvwdLVJsfwcA==:117 a=GsOEXm/OWkKvwdLVJsfwcA==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=GW1xBdLrtEIA:10 a=zstS-IiYAAAA:8 a=tWcsRGI3RrjykUt0rBkA:9 a=rlPfv9juX2VJ5hgq:21 a=MuJzg3V1e9crYw4V:21 a=6gHWnqlhKxM0TE8C:21 a=4G6NA9xxw8l3yy4pmD5M:22 Received: from 71-218-192-86.hlrn.qwest.net ([71.218.192.86]:56110 helo=bapiya.Home) by box522.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_1) (envelope-from ) id 1bojhT-0006Nj-RD; Mon, 26 Sep 2016 22:09:00 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [RFA 11/22] Change command stats reporting to use class Date: Mon, 26 Sep 2016 22:08:39 -0600 Message-Id: <1474949330-4307-12-git-send-email-tom@tromey.com> In-Reply-To: <1474949330-4307-1-git-send-email-tom@tromey.com> References: <1474949330-4307-1-git-send-email-tom@tromey.com> X-BWhitelist: no X-Exim-ID: 1bojhT-0006Nj-RD X-Source-Sender: 71-218-192-86.hlrn.qwest.net (bapiya.Home) [71.218.192.86]:56110 X-Source-Auth: tom+tromey.com X-Email-Count: 23 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTIyLmJsdWVob3N0LmNvbQ== This removes make_command_stats_cleanup in favor of an RAII class. The patch is reasonably straightforward, but keeping the same semantics required reindenting much of captured_main. 2016-09-26 Tom Tromey * 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. --- gdb/ChangeLog | 12 + gdb/event-top.c | 5 +- gdb/main.c | 1101 +++++++++++++++++++++++++++---------------------------- gdb/maint.c | 112 ++---- gdb/maint.h | 39 +- 5 files changed, 632 insertions(+), 637 deletions(-) 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 + * 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 + * 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 */