Change command stats reporting to use class
This removes make_command_stats_cleanup in favor of an RAII class. The patch is reasonably straightforward, but keeping the same semantics without excessive reindentation required splitting captured_main in two. 2016-10-21 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_1): New function. Use scoped_command_stats. (captured_main): Call captured_main_1. * event-top.c (command_handler): Use scoped_command_stats.
This commit is contained in:
parent
6fc31fc73b
commit
1e3b796d58
|
@ -1,3 +1,17 @@
|
||||||
|
2016-10-21 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_1): New function. Use
|
||||||
|
scoped_command_stats.
|
||||||
|
(captured_main): Call captured_main_1.
|
||||||
|
* event-top.c (command_handler): Use scoped_command_stats.
|
||||||
|
|
||||||
2016-10-21 Tom Tromey <tom@tromey.com>
|
2016-10-21 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* mi/mi-main.c (mi_cmd_data_read_memory): Use gdb::unique_ptr.
|
* mi/mi-main.c (mi_cmd_data_read_memory): Use gdb::unique_ptr.
|
||||||
|
|
|
@ -562,13 +562,12 @@ void
|
||||||
command_handler (char *command)
|
command_handler (char *command)
|
||||||
{
|
{
|
||||||
struct ui *ui = current_ui;
|
struct ui *ui = current_ui;
|
||||||
struct cleanup *stat_chain;
|
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
if (ui->instream == ui->stdin_stream)
|
if (ui->instream == ui->stdin_stream)
|
||||||
reinitialize_more_filter ();
|
reinitialize_more_filter ();
|
||||||
|
|
||||||
stat_chain = make_command_stats_cleanup (1);
|
scoped_command_stats stat_reporter (true);
|
||||||
|
|
||||||
/* Do not execute commented lines. */
|
/* Do not execute commented lines. */
|
||||||
for (c = command; *c == ' ' || *c == '\t'; c++)
|
for (c = command; *c == ' ' || *c == '\t'; c++)
|
||||||
|
@ -580,8 +579,6 @@ command_handler (char *command)
|
||||||
/* Do any commands attached to breakpoint we stopped at. */
|
/* Do any commands attached to breakpoint we stopped at. */
|
||||||
bpstat_do_actions ();
|
bpstat_do_actions ();
|
||||||
}
|
}
|
||||||
|
|
||||||
do_cleanups (stat_chain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append RL, an input line returned by readline or one of its
|
/* Append RL, an input line returned by readline or one of its
|
||||||
|
|
25
gdb/main.c
25
gdb/main.c
|
@ -441,12 +441,12 @@ typedef struct cmdarg {
|
||||||
/* Define type VEC (cmdarg_s). */
|
/* Define type VEC (cmdarg_s). */
|
||||||
DEF_VEC_O (cmdarg_s);
|
DEF_VEC_O (cmdarg_s);
|
||||||
|
|
||||||
static int
|
static void
|
||||||
captured_main (void *data)
|
captured_main_1 (struct captured_main_args *context)
|
||||||
{
|
{
|
||||||
struct captured_main_args *context = (struct captured_main_args *) data;
|
|
||||||
int argc = context->argc;
|
int argc = context->argc;
|
||||||
char **argv = context->argv;
|
char **argv = context->argv;
|
||||||
|
|
||||||
static int quiet = 0;
|
static int quiet = 0;
|
||||||
static int set_args = 0;
|
static int set_args = 0;
|
||||||
static int inhibit_home_gdbinit = 0;
|
static int inhibit_home_gdbinit = 0;
|
||||||
|
@ -486,14 +486,14 @@ captured_main (void *data)
|
||||||
int save_auto_load;
|
int save_auto_load;
|
||||||
struct objfile *objfile;
|
struct objfile *objfile;
|
||||||
|
|
||||||
struct cleanup *pre_stat_chain;
|
struct cleanup *chain;
|
||||||
|
|
||||||
#ifdef HAVE_SBRK
|
#ifdef HAVE_SBRK
|
||||||
/* Set this before calling make_command_stats_cleanup. */
|
/* Set this before constructing scoped_command_stats. */
|
||||||
lim_at_start = (char *) sbrk (0);
|
lim_at_start = (char *) sbrk (0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pre_stat_chain = make_command_stats_cleanup (0);
|
scoped_command_stats stat_reporter (false);
|
||||||
|
|
||||||
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
|
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
|
||||||
setlocale (LC_MESSAGES, "");
|
setlocale (LC_MESSAGES, "");
|
||||||
|
@ -510,7 +510,7 @@ captured_main (void *data)
|
||||||
notice_open_fds ();
|
notice_open_fds ();
|
||||||
save_original_signals_state ();
|
save_original_signals_state ();
|
||||||
|
|
||||||
make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
|
chain = make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
|
||||||
dirsize = 1;
|
dirsize = 1;
|
||||||
dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
|
dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
|
||||||
ndir = 0;
|
ndir = 0;
|
||||||
|
@ -1139,8 +1139,15 @@ captured_main (void *data)
|
||||||
quit_force (NULL, 0);
|
quit_force (NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show time and/or space usage. */
|
do_cleanups (chain);
|
||||||
do_cleanups (pre_stat_chain);
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
captured_main (void *data)
|
||||||
|
{
|
||||||
|
struct captured_main_args *context = (struct captured_main_args *) data;
|
||||||
|
|
||||||
|
captured_main_1 (context);
|
||||||
|
|
||||||
/* NOTE: cagney/1999-11-07: There is probably no reason for not
|
/* NOTE: cagney/1999-11-07: There is probably no reason for not
|
||||||
moving this loop and the code found in captured_command_loop()
|
moving this loop and the code found in captured_command_loop()
|
||||||
|
|
118
gdb/maint.c
118
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_setlist;
|
||||||
static struct cmd_list_element *per_command_showlist;
|
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
|
/* Set whether to display time statistics to NEW_VALUE
|
||||||
(non-zero means true). */
|
(non-zero means true). */
|
||||||
|
|
||||||
|
@ -827,31 +802,38 @@ count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
|
||||||
*nr_blocks_ptr = nr_blocks;
|
*nr_blocks_ptr = nr_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* As indicated by display_time and display_space, report GDB's elapsed time
|
/* As indicated by display_time and display_space, report GDB's
|
||||||
and space usage from the base time and space provided in ARG, which
|
elapsed time and space usage from the base time and space recorded
|
||||||
must be a pointer to a struct cmd_stat. This function is intended
|
in this object. */
|
||||||
to be called as a cleanup. */
|
|
||||||
|
|
||||||
static void
|
scoped_command_stats::~scoped_command_stats ()
|
||||||
report_command_stats (void *arg)
|
|
||||||
{
|
{
|
||||||
struct cmd_stats *start_stats = (struct cmd_stats *) arg;
|
/* Early exit if we're not reporting any stats. It can be expensive to
|
||||||
int msg_type = start_stats->msg_type;
|
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 (m_msg_type
|
||||||
|
&& !per_command_time
|
||||||
|
&& !per_command_space
|
||||||
|
&& !per_command_symtab)
|
||||||
|
return;
|
||||||
|
|
||||||
if (start_stats->time_enabled && per_command_time)
|
if (m_time_enabled && per_command_time)
|
||||||
{
|
{
|
||||||
long cmd_time = get_run_time () - start_stats->start_cpu_time;
|
long cmd_time = get_run_time () - m_start_cpu_time;
|
||||||
struct timeval now_wall_time, delta_wall_time, wait_time;
|
struct timeval now_wall_time, delta_wall_time, wait_time;
|
||||||
|
|
||||||
gettimeofday (&now_wall_time, NULL);
|
gettimeofday (&now_wall_time, NULL);
|
||||||
timeval_sub (&delta_wall_time,
|
timeval_sub (&delta_wall_time,
|
||||||
&now_wall_time, &start_stats->start_wall_time);
|
&now_wall_time, &m_start_wall_time);
|
||||||
|
|
||||||
/* Subtract time spend in prompt_for_continue from walltime. */
|
/* Subtract time spend in prompt_for_continue from walltime. */
|
||||||
wait_time = get_prompt_for_continue_wait_time ();
|
wait_time = get_prompt_for_continue_wait_time ();
|
||||||
timeval_sub (&delta_wall_time, &delta_wall_time, &wait_time);
|
timeval_sub (&delta_wall_time, &delta_wall_time, &wait_time);
|
||||||
|
|
||||||
printf_unfiltered (msg_type == 0
|
printf_unfiltered (!m_msg_type
|
||||||
? _("Startup time: %ld.%06ld (cpu), %ld.%06ld (wall)\n")
|
? _("Startup time: %ld.%06ld (cpu), %ld.%06ld (wall)\n")
|
||||||
: _("Command execution time: %ld.%06ld (cpu), %ld.%06ld (wall)\n"),
|
: _("Command execution time: %ld.%06ld (cpu), %ld.%06ld (wall)\n"),
|
||||||
cmd_time / 1000000, cmd_time % 1000000,
|
cmd_time / 1000000, cmd_time % 1000000,
|
||||||
|
@ -859,15 +841,15 @@ report_command_stats (void *arg)
|
||||||
(long) delta_wall_time.tv_usec);
|
(long) delta_wall_time.tv_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start_stats->space_enabled && per_command_space)
|
if (m_space_enabled && per_command_space)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SBRK
|
#ifdef HAVE_SBRK
|
||||||
char *lim = (char *) sbrk (0);
|
char *lim = (char *) sbrk (0);
|
||||||
|
|
||||||
long space_now = lim - lim_at_start;
|
long space_now = lim - lim_at_start;
|
||||||
long space_diff = space_now - start_stats->start_space;
|
long space_diff = space_now - m_start_space;
|
||||||
|
|
||||||
printf_unfiltered (msg_type == 0
|
printf_unfiltered (!m_msg_type
|
||||||
? _("Space used: %ld (%s%ld during startup)\n")
|
? _("Space used: %ld (%s%ld during startup)\n")
|
||||||
: _("Space used: %ld (%s%ld for this command)\n"),
|
: _("Space used: %ld (%s%ld for this command)\n"),
|
||||||
space_now,
|
space_now,
|
||||||
|
@ -876,7 +858,7 @@ report_command_stats (void *arg)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start_stats->symtab_enabled && per_command_symtab)
|
if (m_symtab_enabled && per_command_symtab)
|
||||||
{
|
{
|
||||||
int nr_symtabs, nr_compunit_symtabs, nr_blocks;
|
int nr_symtabs, nr_compunit_symtabs, nr_blocks;
|
||||||
|
|
||||||
|
@ -885,54 +867,32 @@ report_command_stats (void *arg)
|
||||||
" #compunits: %d (+%d),"
|
" #compunits: %d (+%d),"
|
||||||
" #blocks: %d (+%d)\n"),
|
" #blocks: %d (+%d)\n"),
|
||||||
nr_symtabs,
|
nr_symtabs,
|
||||||
nr_symtabs - start_stats->start_nr_symtabs,
|
nr_symtabs - m_start_nr_symtabs,
|
||||||
nr_compunit_symtabs,
|
nr_compunit_symtabs,
|
||||||
(nr_compunit_symtabs
|
(nr_compunit_symtabs
|
||||||
- start_stats->start_nr_compunit_symtabs),
|
- m_start_nr_compunit_symtabs),
|
||||||
nr_blocks,
|
nr_blocks,
|
||||||
nr_blocks - start_stats->start_nr_blocks);
|
nr_blocks - m_start_nr_blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a cleanup that reports time and space used since its creation.
|
scoped_command_stats::scoped_command_stats (bool msg_type)
|
||||||
MSG_TYPE is zero for gdb startup, otherwise it is one(1) to report
|
: m_msg_type (msg_type)
|
||||||
data for individual commands. */
|
|
||||||
|
|
||||||
struct cleanup *
|
|
||||||
make_command_stats_cleanup (int msg_type)
|
|
||||||
{
|
{
|
||||||
struct cmd_stats *new_stat;
|
if (!m_msg_type || per_command_space)
|
||||||
|
|
||||||
/* 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
|
#ifdef HAVE_SBRK
|
||||||
char *lim = (char *) sbrk (0);
|
char *lim = (char *) sbrk (0);
|
||||||
new_stat->start_space = lim - lim_at_start;
|
m_start_space = lim - lim_at_start;
|
||||||
new_stat->space_enabled = 1;
|
m_space_enabled = 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg_type == 0 || per_command_time)
|
if (msg_type == 0 || per_command_time)
|
||||||
{
|
{
|
||||||
new_stat->start_cpu_time = get_run_time ();
|
m_start_cpu_time = get_run_time ();
|
||||||
gettimeofday (&new_stat->start_wall_time, NULL);
|
gettimeofday (&m_start_wall_time, NULL);
|
||||||
new_stat->time_enabled = 1;
|
m_time_enabled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg_type == 0 || per_command_symtab)
|
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;
|
int nr_symtabs, nr_compunit_symtabs, nr_blocks;
|
||||||
|
|
||||||
count_symtabs_and_blocks (&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;
|
m_start_nr_symtabs = nr_symtabs;
|
||||||
new_stat->start_nr_compunit_symtabs = nr_compunit_symtabs;
|
m_start_nr_compunit_symtabs = nr_compunit_symtabs;
|
||||||
new_stat->start_nr_blocks = nr_blocks;
|
m_start_nr_blocks = nr_blocks;
|
||||||
new_stat->symtab_enabled = 1;
|
m_symtab_enabled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initalize timer to keep track of how long we waited for the user. */
|
/* Initalize timer to keep track of how long we waited for the user. */
|
||||||
reset_prompt_for_continue_wait_time ();
|
reset_prompt_for_continue_wait_time ();
|
||||||
|
|
||||||
return make_cleanup_dtor (report_command_stats, new_stat, xfree);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle unknown "mt set per-command" arguments.
|
/* Handle unknown "mt set per-command" arguments.
|
||||||
|
|
37
gdb/maint.h
37
gdb/maint.h
|
@ -23,9 +23,40 @@ extern void set_per_command_time (int);
|
||||||
|
|
||||||
extern void set_per_command_space (int);
|
extern void set_per_command_space (int);
|
||||||
|
|
||||||
/* Note: There's no set_per_command_symtab on purpose.
|
/* Records a run time and space usage to be used as a base for
|
||||||
Symtab stats aren't yet as useful for --statistics output. */
|
reporting elapsed time or change in space. */
|
||||||
|
|
||||||
extern struct cleanup *make_command_stats_cleanup (int);
|
class scoped_command_stats
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit scoped_command_stats (bool 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. */
|
||||||
|
bool m_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 m_time_enabled : 1;
|
||||||
|
int m_space_enabled : 1;
|
||||||
|
int m_symtab_enabled : 1;
|
||||||
|
long m_start_cpu_time;
|
||||||
|
struct timeval m_start_wall_time;
|
||||||
|
long m_start_space;
|
||||||
|
/* Total number of symtabs (over all objfiles). */
|
||||||
|
int m_start_nr_symtabs;
|
||||||
|
/* A count of the compunits. */
|
||||||
|
int m_start_nr_compunit_symtabs;
|
||||||
|
/* Total number of blocks. */
|
||||||
|
int m_start_nr_blocks;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* MAINT_H */
|
#endif /* MAINT_H */
|
||||||
|
|
Loading…
Reference in New Issue