From d4ecc19cc520480ef3da7600006c41cef850839d Mon Sep 17 00:00:00 2001 From: Zoltan Somogyi Date: Wed, 8 Aug 2018 10:48:54 +1000 Subject: [PATCH] Improve mdb's "print io" command. trace/mercury_trace_cmd_browsing.c: Lift the hard-wired limit on printing a maximum of 20 I/O actions at once by adding the option "-m max" to the "print io" command. Keep the default at 20 for its "print io" form, which prints the next batch of I/O actions, but move it up to 500 for the "print io *" form, which is intended to print *all* I/O actions. Use separate functions for processing the options of the "print" and "browse" mdb commands. The new -m option applies only to the print command, while the existing -w and -x options apply only to the browse command. Make "print io N" print the same out-of-range error message as "print io N-M". This inconsistency was an oversight. doc/user_guide.texi: Document the changes above. Document some previously existing aspects of the "print io" command that should have been documented but weren't. Change some other documentation to refer to "I/O actions" instead of just "io actions". tests/debugger/tabled_read_decl.exp: Expect the updated error message for an out-of-range "print io N". tests/debugger/tabled_typeclass.{inp,exp,exp2}: Print the I/O actions we want using a single "print -m 100 io *" command. --- doc/user_guide.texi | 86 ++++++++++---- tests/debugger/tabled_read_decl.exp | 2 +- tests/debugger/tabled_typeclass.exp | 3 +- tests/debugger/tabled_typeclass.exp2 | 4 +- tests/debugger/tabled_typeclass.inp | 3 +- trace/mercury_trace_cmd_browsing.c | 161 ++++++++++++++++++++++----- 6 files changed, 203 insertions(+), 56 deletions(-) diff --git a/doc/user_guide.texi b/doc/user_guide.texi index a99e59e15..3b6731b79 100644 --- a/doc/user_guide.texi +++ b/doc/user_guide.texi @@ -2999,9 +2999,47 @@ Reports an error if the current event does not refer to such a port. The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, and @samp{-v} or @samp{--verbose} specify the format to use for printing. @sp 1 +@item print action limits +Prints the numbers of the lowest and highest numbered +I/O actions executed and recorded by the program, if any. +@sp 1 @item print [-fpv] action @var{num} Prints a representation -of the @var{num}'th I/O action executed by the program. +of the @var{num}'th I/O action executed by the program, +if there was such an action and if it was recorded. +@sp 1 +The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, +and @samp{-v} or @samp{--verbose} specify the format to use for printing. +@sp 1 +@item print [-fpv] action @var{min}-@var{max} +Prints a representation of the I/O actions executed by the program +from the @var{min}'th to the @var{min}'th, +if there were such actions and if they were recorded. +@sp 1 +The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, +and @samp{-v} or @samp{--verbose} specify the format to use for printing. +@sp 1 +@item print [-fpv] [-m @var{max}] action +If no I/O actions have been printed yet, +or if the last mdb command to print I/O actions was not successful, +prints a representation of the first @var{max} I/O actions +executed and recorded by the program. +If there was an mdb command to print I/O actions and it was successful, +prints a representation of the next @var{max} I/O actions +executed and recorded by the program. +@sp 1 +The value of @var{max} is given by the @samp{-m} option. +If the option is not specified, the default is 20. +@sp 1 +The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, +and @samp{-v} or @samp{--verbose} specify the format to use for printing. +@sp 1 +@item print [-fpv] [-m @var{max}] action * +Prints a representation of the first @var{max} I/O actions +executed and recorded by the program. +@sp 1 +The value of @var{max} is given by the @samp{-m} option. +If the option is not specified, the default is 500. @sp 1 The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, and @samp{-v} or @samp{--verbose} specify the format to use for printing. @@ -3048,12 +3086,13 @@ the goal of the current call in its present state of instantiation. @sp 1 The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, and @samp{-v} or @samp{--verbose} specify the format to use for browsing. -The @samp{-x} or @samp{--xml} option tells mdb to dump the goal to an XML file -and then invoke an XML browser on the file. The XML filename as well as the -command to invoke the XML browser can be set using the @samp{set} command. See -the documentation for @samp{set} for more details. -The @samp{-w} or @samp{--web} option tells mdb to dump the goal to an HTML file -and then invoke a web browser on that file. +The @samp{-x} or @samp{--xml} option tells mdb +to dump the goal to an XML file and then invoke an XML browser on the file. +The XML filename as well as the command to invoke the XML browser +can be set using the @samp{set} command. +See the documentation for @samp{set} for more details. +The @samp{-w} or @samp{--web} option tells mdb +to dump the goal to an HTML file and then invoke a web browser on that file. @sp 1 @item browse [-fpvxw] exception Invokes the interactive term browser to browse @@ -3062,25 +3101,32 @@ Reports an error if the current event does not refer to such a port. @sp 1 The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, and @samp{-v} or @samp{--verbose} specify the format to use for browsing. -The @samp{-x} or @samp{--xml} option tells mdb to dump the exception to an -XML file and then invoke an XML browser on the file. The XML filename as well -as the command to invoke the XML browser can be set using the @samp{set} -command. See the documentation for @samp{set} for more details. -The @samp{-w} or @samp{--web} option tells mdb to dump the exception to an -HTML file and then invoke a web browser on that file. +The @samp{-x} or @samp{--xml} option tells mdb +to dump the exception to an XML file +and then invoke an XML browser on the file. +The XML filename as well as the command to invoke the XML browser +can be set using the @samp{set} command. +See the documentation for @samp{set} for more details. +The @samp{-w} or @samp{--web} option tells mdb +to dump the exception to an HTML file +and then invoke a web browser on that file. @sp 1 @item browse [-fpvxw] action @var{num} Invokes an interactive term browser to browse a representation -of the @var{num}'th I/O action executed by the program. +of the @var{num}'th I/O action executed by the program, +if there was such an action and if it was recorded. @sp 1 The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty}, and @samp{-v} or @samp{--verbose} specify the format to use for browsing. -The @samp{-x} or @samp{--xml} option tells mdb to dump the io action -representation to an XML file and then invoke an XML browser on the file. The -XML filename as well as the command to invoke the XML browser can be set using -the @samp{set} command. See the documentation for @samp{set} for more details. -The @samp{-w} or @samp{--web} option tells mdb to dump the io action -representation to an HTML file and then invoke a web browser on that file. +The @samp{-x} or @samp{--xml} option tells mdb +to dump the I/O action representation to an XML file +and then invoke an XML browser on the file. +The XML filename as well as the command to invoke the XML browser +can be set using the @samp{set} command. +See the documentation for @samp{set} for more details. +The @samp{-w} or @samp{--web} option tells mdb +to dump the I/O action representation to an HTML file, +and then invoke a web browser on that file. @c @sp 1 @c @item browse [-fpvx] proc_body @c Invokes an interactive term browser to browse a representation diff --git a/tests/debugger/tabled_read_decl.exp b/tests/debugger/tabled_read_decl.exp index 11b0986db..484dea8f6 100644 --- a/tests/debugger/tabled_read_decl.exp +++ b/tests/debugger/tabled_read_decl.exp @@ -87,6 +87,6 @@ poly_read_char_code(list(character), c_pointer(0xXXXX), ['a', 'b', 'c'], 54) mdb> print action 8 poly_read_char_code(list(character), c_pointer(0xXXXX), ['a', 'b', 'c'], 10) mdb> print action 9 -mdb: I/O action number not in range. +I/O tabling has only recorded actions 0 to 8. mdb> continue -S 789 diff --git a/tests/debugger/tabled_typeclass.exp b/tests/debugger/tabled_typeclass.exp index e5b4d2019..a8136563d 100644 --- a/tests/debugger/tabled_typeclass.exp +++ b/tests/debugger/tabled_typeclass.exp @@ -17,14 +17,13 @@ mdb> finish E2: C1 EXIT pred tabled_typeclass.main/2-0 (det) mdb> print io limits I/O tabling has recorded actions 0 to 29. -mdb> print io 0-5 +mdb> print -m 100 io * action 0: tc_action("the arguments are not available due to the presence of one or more type class constraints") action 1: output_stream_2(stream(1, output, preopen, stdout)) action 2: do_write_int(<>, 1, <>) action 3: output_stream_2(stream(1, output, preopen, stdout)) action 4: do_write_char(<>, '\n', <>) action 5: notc_action(status, status_success, 2) -mdb> print io 6-29 action 6: output_stream_2(stream(1, output, preopen, stdout)) action 7: do_write_int(<>, 2, <>) action 8: output_stream_2(stream(1, output, preopen, stdout)) diff --git a/tests/debugger/tabled_typeclass.exp2 b/tests/debugger/tabled_typeclass.exp2 index 1ef49b7c8..3595c4c94 100644 --- a/tests/debugger/tabled_typeclass.exp2 +++ b/tests/debugger/tabled_typeclass.exp2 @@ -17,15 +17,13 @@ mdb> finish E2: C1 EXIT pred tabled_typeclass.main/2-0 (det) mdb> print io limits I/O tabling has recorded actions 0 to 5. -mdb> print io 0-5 +mdb> print -m 100 io * action 0: tc_action("the arguments are not available due to the presence of one or more type class constraints") action 1: notc_action(status, status_success, 2) action 2: tc_action("the arguments are not available due to the presence of one or more type class constraints") action 3: notc_action(status, status_no_memory, 4) action 4: tc_action("the arguments are not available due to the presence of one or more type class constraints") action 5: notc_action(status, status_null_pointer, 6) -mdb> print io 6-29 -I/O tabling has only recorded actions 0 to 5. mdb> retry -f E1: C1 CALL pred tabled_typeclass.main/2-0 (det) mdb> continue diff --git a/tests/debugger/tabled_typeclass.inp b/tests/debugger/tabled_typeclass.inp index 1649a899f..904821a5a 100644 --- a/tests/debugger/tabled_typeclass.inp +++ b/tests/debugger/tabled_typeclass.inp @@ -5,7 +5,6 @@ table_io allow table_io start finish print io limits -print io 0-5 -print io 6-29 +print -m 100 io * retry -f continue diff --git a/trace/mercury_trace_cmd_browsing.c b/trace/mercury_trace_cmd_browsing.c index 5a821df9f..00f694142 100644 --- a/trace/mercury_trace_cmd_browsing.c +++ b/trace/mercury_trace_cmd_browsing.c @@ -67,20 +67,25 @@ static const char *MR_trace_new_source_window(const char *window_cmd, int timeout, MR_bool force, MR_bool verbose, MR_bool split); -static MR_bool MR_trace_options_detailed(MR_bool *detailed, char ***words, - int *word_count); +static MR_bool MR_trace_options_detailed(MR_bool *detailed, + char ***words, int *word_count); static MR_bool MR_trace_options_stack_trace(MR_bool *print_all, MR_bool *detailed, MR_SpecLineLimit *line_limit, MR_SpecLineLimit *clique_line_limit, MR_FrameLimit *frame_limit, char ***words, int *word_count); -static MR_bool MR_trace_options_format(MR_BrowseFormat *format, - MR_bool *xml, MR_bool *web, char ***words, int *word_count); +static MR_bool MR_trace_options_print(MR_BrowseFormat *format, + MR_Unsigned *max_printed_actions, + MR_bool *set_max_printed_actions, + char ***words, int *word_count); +static MR_bool MR_trace_options_browse(MR_BrowseFormat *format, + MR_bool *xml, MR_bool *web, + char ***words, int *word_count); static MR_bool MR_trace_options_view(const char **window_cmd, const char **server_cmd, const char **server_name, MR_Unsigned *timeout, MR_bool *force, MR_bool *verbose, - MR_bool *split, MR_bool *close_window, char ***words, - int *word_count); + MR_bool *split, MR_bool *close_window, + char ***words, int *word_count); static MR_bool MR_trace_options_diff(MR_Unsigned *start, MR_Unsigned *max, char ***words, int *word_count); static MR_bool MR_trace_options_dump(MR_bool *quiet, MR_bool *xml, @@ -208,15 +213,16 @@ MR_trace_cmd_held_vars(char **words, int word_count, MR_TraceCmdInfo *cmd, return KEEP_INTERACTING; } -#define MR_MAX_NUM_IO_ACTIONS_TO_PRINT 20 +#define MR_NEXT_NUM_IO_ACTIONS_TO_PRINT 20 +#define MR_ALL_NUM_IO_ACTIONS_TO_PRINT 500 MR_Next MR_trace_cmd_print(char **words, int word_count, MR_TraceCmdInfo *cmd, MR_EventInfo *event_info, MR_Code **jumpaddr) { MR_BrowseFormat format; - MR_bool xml; - MR_bool web; + MR_Unsigned max_printed_actions; + MR_bool set_max_printed_actions; const char *problem; MR_Unsigned action; MR_Unsigned lo_action; @@ -224,15 +230,11 @@ MR_trace_cmd_print(char **words, int word_count, MR_TraceCmdInfo *cmd, static MR_bool have_next_io_action = MR_FALSE; static MR_Unsigned next_io_action = 0; - if (! MR_trace_options_format(&format, &xml, &web, &words, &word_count)) { + if (! MR_trace_options_print(&format, + &max_printed_actions, &set_max_printed_actions, &words, &word_count)) + { // The usage message has already been printed. ; - } else if (xml) { - // The --xml option is not valid for print. - MR_trace_usage_cur_cmd(); - } else if (web) { - // The --web option is not valid for print. - MR_trace_usage_cur_cmd(); } else if (word_count == 1) { problem = MR_trace_browse_one_goal(MR_mdb_out, MR_trace_browse_goal_internal, MR_BROWSE_CALLER_PRINT, format); @@ -258,6 +260,10 @@ MR_trace_cmd_print(char **words, int word_count, MR_TraceCmdInfo *cmd, { MR_Unsigned num_printed_actions; + if (!set_max_printed_actions) { + max_printed_actions = MR_NEXT_NUM_IO_ACTIONS_TO_PRINT; + } + if (MR_io_tabling_phase == MR_IO_TABLING_BEFORE) { fflush(MR_mdb_out); fprintf(MR_mdb_err, @@ -285,7 +291,7 @@ MR_trace_cmd_print(char **words, int word_count, MR_TraceCmdInfo *cmd, lo_action = MR_io_tabling_start; } - hi_action = lo_action + MR_MAX_NUM_IO_ACTIONS_TO_PRINT; + hi_action = lo_action + max_printed_actions; if (hi_action >= MR_io_tabling_counter_hwm) { hi_action = MR_io_tabling_counter_hwm - 1; } @@ -357,6 +363,19 @@ MR_trace_cmd_print(char **words, int word_count, MR_TraceCmdInfo *cmd, MR_io_tabling_start, MR_io_tabling_counter_hwm - 1); fflush(MR_mdb_out); } else if (MR_trace_is_natural_number(words[2], &action)) { + if (! (MR_io_tabling_start <= action + && action < MR_io_tabling_counter_hwm)) + { + fflush(MR_mdb_out); + fprintf(MR_mdb_err, + "I/O tabling has only recorded actions " + "%" MR_INTEGER_LENGTH_MODIFIER "u to " + "%" MR_INTEGER_LENGTH_MODIFIER "u.\n", + MR_io_tabling_start, MR_io_tabling_counter_hwm - 1); + have_next_io_action = MR_FALSE; + return KEEP_INTERACTING; + } + problem = MR_trace_browse_action(MR_mdb_out, action, MR_trace_browse_goal_internal, MR_BROWSE_CALLER_PRINT, format); @@ -411,22 +430,37 @@ MR_trace_cmd_print(char **words, int word_count, MR_TraceCmdInfo *cmd, next_io_action = hi_action + 1; have_next_io_action = MR_TRUE; } else if (MR_streq(words[2], "*")) { + if (!set_max_printed_actions) { + max_printed_actions = MR_ALL_NUM_IO_ACTIONS_TO_PRINT; + } + lo_action = MR_io_tabling_start; hi_action = MR_io_tabling_counter_hwm - 1; - if (lo_action + MR_MAX_NUM_IO_ACTIONS_TO_PRINT < hi_action) { + if (lo_action + max_printed_actions < hi_action) { fflush(MR_mdb_out); fprintf(MR_mdb_err, "I/O tabling has recorded " "%" MR_INTEGER_LENGTH_MODIFIER "d actions, " "numbered %" MR_INTEGER_LENGTH_MODIFIER "u to " - "%" MR_INTEGER_LENGTH_MODIFIER "u.\n" - "Without an explicit request, " - "only a maximum of %d actions will be printed.\n", + "%" MR_INTEGER_LENGTH_MODIFIER "u.\n", MR_io_tabling_counter_hwm + MR_io_tabling_start - 1, - MR_io_tabling_start, MR_io_tabling_counter_hwm - 1, - MR_MAX_NUM_IO_ACTIONS_TO_PRINT); - return KEEP_INTERACTING; + MR_io_tabling_start, MR_io_tabling_counter_hwm - 1); + if (set_max_printed_actions) { + fprintf(MR_mdb_err, + "Following your request via the -m option, " + "only the first %" MR_INTEGER_LENGTH_MODIFIER "d " + "actions will be printed.\n", + max_printed_actions); + } else { + fprintf(MR_mdb_err, + "Without your explicit request via the -m option, " + "only the default maximum of %d actions " + "will be printed.\n", + max_printed_actions); + } + + hi_action = lo_action + max_printed_actions - 1; } for (action = lo_action; action <= hi_action; action++) { @@ -467,7 +501,7 @@ MR_trace_cmd_browse(char **words, int word_count, MR_TraceCmdInfo *cmd, MR_Browser browser; const char *problem; - if (! MR_trace_options_format(&format, &xml, &web, &words, &word_count)) { + if (! MR_trace_options_browse(&format, &xml, &web, &words, &word_count)) { // The usage message has already been printed. ; } else { @@ -1291,8 +1325,79 @@ MR_trace_options_stack_trace(MR_bool *print_all, MR_bool *detailed, return MR_TRUE; } -static struct MR_option MR_trace_format_opts[] = +static struct MR_option MR_trace_print_opts[] = { + // Please keep the formatting options in sync with MR_trace_browse_opts. + { "flat", MR_no_argument, NULL, 'f' }, + { "raw_pretty", MR_no_argument, NULL, 'r' }, + { "verbose", MR_no_argument, NULL, 'v' }, + { "pretty", MR_no_argument, NULL, 'p' }, + { "max", MR_required_argument, NULL, 'm' }, + { NULL, MR_no_argument, NULL, 0 } +}; + +static MR_bool +MR_trace_options_print(MR_BrowseFormat *format, + MR_Unsigned *max_printed_actions, MR_bool *set_max_printed_actions, + char ***words, int *word_count) +{ + int c; + + *format = MR_BROWSE_DEFAULT_FORMAT; + *max_printed_actions = -1; + *set_max_printed_actions = MR_FALSE; + MR_optind = 0; + while ((c = MR_getopt_long(*word_count, *words, "frvpm:", + MR_trace_print_opts, NULL)) != EOF) + { + switch (c) { + + case 'f': + *format = MR_BROWSE_FORMAT_FLAT; + break; + + case 'r': + *format = MR_BROWSE_FORMAT_RAW_PRETTY; + break; + + case 'v': + *format = MR_BROWSE_FORMAT_VERBOSE; + break; + + case 'p': + *format = MR_BROWSE_FORMAT_PRETTY; + break; + + case 'm': + if (! MR_trace_is_natural_number(MR_optarg, + max_printed_actions)) + { + MR_trace_usage_cur_cmd(); + return MR_FALSE; + } + if (*max_printed_actions == 0) { + // Printing a maximum of zero I/O actions + // does not make any sense. + MR_trace_usage_cur_cmd(); + return MR_FALSE; + } + *set_max_printed_actions = MR_TRUE; + break; + + default: + MR_trace_usage_cur_cmd(); + return MR_FALSE; + } + } + + *words = *words + MR_optind - 1; + *word_count = *word_count - MR_optind + 1; + return MR_TRUE; +} + +static struct MR_option MR_trace_browse_opts[] = +{ + // Please keep the formatting options in sync with MR_trace_print_opts. { "flat", MR_no_argument, NULL, 'f' }, { "raw_pretty", MR_no_argument, NULL, 'r' }, { "verbose", MR_no_argument, NULL, 'v' }, @@ -1303,7 +1408,7 @@ static struct MR_option MR_trace_format_opts[] = }; static MR_bool -MR_trace_options_format(MR_BrowseFormat *format, MR_bool *xml, MR_bool *web, +MR_trace_options_browse(MR_BrowseFormat *format, MR_bool *xml, MR_bool *web, char ***words, int *word_count) { int c; @@ -1313,7 +1418,7 @@ MR_trace_options_format(MR_BrowseFormat *format, MR_bool *xml, MR_bool *web, *web = MR_FALSE; MR_optind = 0; while ((c = MR_getopt_long(*word_count, *words, "frvpxw", - MR_trace_format_opts, NULL)) != EOF) + MR_trace_browse_opts, NULL)) != EOF) { switch (c) {