[m-rev.] for review: add --module option for dice mdb command
Ian MacLarty
maclarty at cs.mu.OZ.AU
Sat Feb 12 15:36:51 AEDT 2005
For review by anyone.
Estimated hours taken: 6
Branches: main
Add a --module option to the mdb dice command to limit output to a specific
module or package.
Write out the trace counts even if the program aborts with an exception.
browser/dice.m
Handle the --module option by adding an extra argument to the
read_dice_to_string predicate which is called from mdb.
doc/user_guide.texi
Document the --module option.
mdbcomp/prim_data.m
Add a predicate to check if one module is a sub-module of another.
runtime/mercury_trace_base.c
runtime/mercury_trace_base.h
Add a function which writes the trace counts out to the file
indicated by the symbolic constant MERCURY_TRACE_COUNTS_FILE_NAME.
Move the symbolic constant MERCURY_TRACE_COUNTS_FILE_NAME from
runtime/mercury_wrapper.c to runtime/mercury_trace_base.h, so it
is accessible from the above function.
runtime/mercury_wrapper.c
Register a function to write the trace counts to a file when the
program aborts with an exception.
Call the same function when the program terminates normally.
tests/debugger/dice.exp
tests/debugger/dice.inp
Test the new --module option.
trace/mercury_trace_internal.c
Add and handle the new --module option.
Index: browser/dice.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/dice.m,v
retrieving revision 1.1
diff -u -r1.1 dice.m
--- browser/dice.m 10 Feb 2005 04:10:27 -0000 1.1
+++ browser/dice.m 10 Feb 2005 06:08:37 -0000
@@ -51,7 +51,7 @@
:- pred read_trace_counts_list(string::in, read_trace_counts_list_result::out,
io::di, io::uo) is det.
- % read_dice_to_string(PassFiles, FailFile, SortStr, N, DiceStr,
+ % read_dice_to_string(PassFiles, FailFile, SortStr, N, Module, DiceStr,
% Problem, !IO).
% Read the trace_counts in the list of files in the file named
% PassFiles, interpreting them as passing slices; read the
@@ -61,13 +61,15 @@
% SortStr can be any combination of the letters "sSpPfP" and
% indicates how the dice is to be sorted. See the documentation
% for the `dice' command in the user guide for an explaination of the
- % sort string. If there was a problem reading the trace_counts then
- % Problem will contain a string describing the problem encountered and
- % DiceStr will be the empty string, otherwise Problem will be the
- % empty string.
+ % sort string. If Module is not the empty string then only labels
+ % from the named module will be included in the dice string, otherwise
+ % all modules will be included. If there was a problem reading the
+ % trace_counts then Problem will contain a string describing the
+ % problem encountered and DiceStr will be the empty string, otherwise
+ % Problem will be the empty string.
%
:- pred read_dice_to_string(string::in, string::in, string::in, int::in,
- string::out, string::out, io::di, io::uo) is det.
+ string::in, string::out, string::out, io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
@@ -198,10 +200,11 @@
Result = ok([])
).
-:- pragma export(read_dice_to_string(in, in, in, in, out, out, di, uo),
+:- pragma export(read_dice_to_string(in, in, in, in, in, out, out, di, uo),
"MR_MDB_read_dice_to_string").
-read_dice_to_string(PassFiles, FailFile, SortStr, N, DiceStr, Problem, !IO) :-
+read_dice_to_string(PassFiles, FailFile, SortStr, N, Module, DiceStr, Problem,
+ !IO) :-
(
sort_string_is_valid(SortStr)
->
@@ -219,8 +222,16 @@
merge_trace_counts(fail, FailTraceCounts,
PassDice, Dice),
LabelCounts = dice_to_label_counts(Dice),
+ ( Module \= "" ->
+ list.filter(label_count_is_for_module(
+ Module), LabelCounts,
+ FilteredLabelCounts)
+ ;
+ FilteredLabelCounts = LabelCounts
+ ),
list.sort(label_count_compare(SortStr),
- LabelCounts, SortedLabelCounts),
+ FilteredLabelCounts,
+ SortedLabelCounts),
(
list.take(N, SortedLabelCounts, Taken)
->
@@ -252,6 +263,17 @@
Problem = "Invalid sort string",
DiceStr = ""
).
+
+:- pred label_count_is_for_module(string::in, label_count::in) is semidet.
+
+label_count_is_for_module(Module,
+ label_count(proc(_, _, SymDeclModule, _, _, _), _, _)) :-
+ string_to_sym_name(Module, ".", SymModule),
+ is_submodule(SymDeclModule, SymModule).
+label_count_is_for_module(Module, label_count(
+ special_proc(_, _, SymTypeModule, _, _, _), _, _)) :-
+ string_to_sym_name(Module, ".", SymModule),
+ is_submodule(SymTypeModule, SymModule).
% Values of this type uniquely identify a label in the program
% and contain some statistics about the execution of the label.
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.417
diff -u -r1.417 user_guide.texi
--- doc/user_guide.texi 10 Feb 2005 04:10:28 -0000 1.417
+++ doc/user_guide.texi 12 Feb 2005 04:12:30 -0000
@@ -3391,7 +3391,7 @@
Clears the histogram printed by @samp{histogram_exp},
i.e.@: sets the counts for all depths to zero.
@sp 1
- at item dice [-p at var{filename}] [-f at var{filename}] [-n at var{num}] [-s[pPfFsS]+] [-o @var{filename}]
+ at item dice [-p at var{filename}] [-f at var{filename}] [-n at var{num}] [-s[pPfFsS]+] [-o @var{filename}] [-m @var{module}]
@kindex dice (mdb command)
Display a program dice on the screen.
@sp 1
@@ -3499,6 +3499,9 @@
will be written to the specified file instead of being displayed on the
screen. Note that the file will be overwritten without warning if it
already exists.
+ at sp 1
+The @samp{-m} or @samp{--module} option limits the output to the given module
+or package.
@end table
@sp 1
Index: mdbcomp/prim_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/mdbcomp/prim_data.m,v
retrieving revision 1.3
diff -u -r1.3 prim_data.m
--- mdbcomp/prim_data.m 10 Feb 2005 04:10:29 -0000 1.3
+++ mdbcomp/prim_data.m 11 Feb 2005 04:22:15 -0000
@@ -132,6 +132,12 @@
:- pred sym_name_to_string(sym_name::in, string::out) is det.
:- func sym_name_to_string(sym_name) = string.
+ % is_submodule(SymName1, SymName2).
+ % True iff SymName1 is a submodule of SymName2.
+ % For example mod1.mod2.mod3 is a submodule of mod1.mod2.
+ %
+:- pred is_submodule(sym_name::in, sym_name::in) is semidet.
+
% insert_module_qualifier(ModuleName, SymName0, SymName):
% prepend the specified ModuleName onto the module
% qualifiers in SymName0, giving SymName.
@@ -187,7 +193,12 @@
sym_name_to_string(ModuleSym, Separator, ModuleName),
string__append_list([ModuleName, Separator, Name], QualName).
+is_submodule(SymName, SymName).
+is_submodule(qualified(SymName1, _), SymName2) :-
+ is_submodule(SymName1, SymName2).
+
special_pred_name_arity(unify, "unify", 2).
special_pred_name_arity(index, "index", 2).
special_pred_name_arity(compare, "compare", 3).
special_pred_name_arity(initialise, "initialise", 1).
+
Index: runtime/mercury_trace_base.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.c,v
retrieving revision 1.62
diff -u -r1.62 mercury_trace_base.c
--- runtime/mercury_trace_base.c 10 Feb 2005 01:00:00 -0000 1.62
+++ runtime/mercury_trace_base.c 11 Feb 2005 03:51:04 -0000
@@ -204,6 +204,22 @@
MR_trace_write_quoted_atom(FILE *fp, const char *atom);
void
+MR_trace_write_label_exec_counts_to_file(void *dummy)
+{
+ FILE *fp;
+
+ fp = fopen(MERCURY_TRACE_COUNTS_FILE_NAME, "w");
+ if (fp != NULL) {
+ MR_do_init_modules_debugger();
+ MR_trace_write_label_exec_counts(fp);
+ (void) fclose(fp);
+ } else {
+ fprintf(stderr, "%s: %s\n",
+ MERCURY_TRACE_COUNTS_FILE_NAME, strerror(errno));
+ }
+}
+
+void
MR_trace_write_label_exec_counts(FILE *fp)
{
const MR_Module_Layout *module;
Index: runtime/mercury_trace_base.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.h,v
retrieving revision 1.43
diff -u -r1.43 mercury_trace_base.h
--- runtime/mercury_trace_base.h 10 Feb 2005 04:10:30 -0000 1.43
+++ runtime/mercury_trace_base.h 11 Feb 2005 03:51:04 -0000
@@ -110,6 +110,15 @@
extern void MR_trace_write_label_exec_counts(FILE *fp);
/*
+** MR_trace_write_label_exec_counts_to_file does the same job as
+** MR_trace_write_label_exec_counts, except that it also opens the file.
+** It's signature allows it to be registered with
+** MR_register_exception_cleanup.
+*/
+
+extern void MR_trace_write_label_exec_counts_to_file(void *dummy);
+
+/*
** MR_trace_init() is called from mercury_runtime_init()
** when the debuggee programs begins, to perform any initialization
** that must be done before any traced Mercury code is executed.
@@ -519,5 +528,7 @@
MR_save_transient_registers(); \
MR_io_tabling_enabled = saved_io_enabled; \
} while (0)
+
+#define MERCURY_TRACE_COUNTS_FILE_NAME ".mercury_trace_counts"
#endif /* MERCURY_TRACE_BASE_H */
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.143
diff -u -r1.143 mercury_wrapper.c
--- runtime/mercury_wrapper.c 28 Jan 2005 07:11:55 -0000 1.143
+++ runtime/mercury_wrapper.c 11 Feb 2005 03:51:04 -0000
@@ -623,6 +623,12 @@
MR_register_module_layout =
MR_insert_module_info_into_module_table;
MR_selected_trace_func_ptr = MR_trace_count;
+ /*
+ ** In case the program terminates with an exception,
+ ** we still want the trace count to be written out.
+ */
+ MR_register_exception_cleanup(
+ MR_trace_write_label_exec_counts_to_file, NULL);
}
/*
@@ -1935,8 +1941,6 @@
/*---------------------------------------------------------------------------*/
-#define MERCURY_TRACE_COUNTS_FILE_NAME ".mercury_trace_counts"
-
int
mercury_runtime_terminate(void)
{
@@ -1964,18 +1968,7 @@
MR_trace_final();
if (MR_trace_count_enabled) {
- FILE *fp;
-
- fp = fopen(MERCURY_TRACE_COUNTS_FILE_NAME, "w");
- if (fp != NULL) {
- MR_do_init_modules_debugger();
- MR_trace_write_label_exec_counts(fp);
- (void) fclose(fp);
- } else {
- fprintf(stderr, "%s: %s\n",
- MERCURY_TRACE_COUNTS_FILE_NAME,
- strerror(errno));
- }
+ MR_trace_write_label_exec_counts_to_file(NULL);
}
#if defined(MR_MPROF_PROFILE_TIME) || defined(MR_MPROF_PROFILE_CALLS) \
Index: tests/debugger/dice.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/dice.exp,v
retrieving revision 1.1
diff -u -r1.1 dice.exp
--- tests/debugger/dice.exp 10 Feb 2005 04:10:31 -0000 1.1
+++ tests/debugger/dice.exp 12 Feb 2005 03:46:51 -0000
@@ -28,7 +28,7 @@
pred dice.msort_n/4-0 <e;e;> dice.m:55 8 (3) 3 0.27
mdb> set fail_trace_count dice.fail
mdb> set pass_trace_counts dice.passes
-mdb> dice -sS
+mdb> dice -sS -m dice
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred dice.merge/3-0 <s2;c2;s2;c4;e;> dice.m:74 0 (0) 1 1.00
pred dice.merge/3-0 <s2;> dice.m:64 10 (3) 4 0.29
@@ -52,7 +52,7 @@
pred dice.merge_sort/2-0 CALL dice.m:31 3 (3) 1 0.25
pred dice.merge_sort/2-0 EXIT dice.m:31 3 (3) 1 0.25
pred dice.merge/3-0 <s2;c2;s2;c4;t;> dice.m:71 10 (3) 3 0.23
-mdb> dice -sSF
+mdb> dice -sSF -m dice
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred dice.merge/3-0 <s2;c2;s2;c4;e;> dice.m:74 0 (0) 1 1.00
pred dice.merge/3-0 <s2;> dice.m:64 10 (3) 4 0.29
@@ -76,12 +76,12 @@
pred dice.merge_sort/2-0 CALL dice.m:31 3 (3) 1 0.25
pred dice.merge_sort/2-0 EXIT dice.m:31 3 (3) 1 0.25
pred dice.merge/3-0 <s2;c2;s2;c4;t;> dice.m:71 10 (3) 3 0.23
-mdb> dice -n 3 -s P
+mdb> dice -n 3 -s P -m dice
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred dice.msort_n/4-0 CALL dice.m:43 19 (3) 7 0.27
pred dice.msort_n/4-0 EXIT dice.m:43 19 (3) 7 0.27
pred dice.msort_n/4-0 <?;> dice.m:39 19 (3) 7 0.27
-mdb> dice -s Fp
+mdb> dice -s Fp -m dice
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred dice.merge/3-0 CALL dice.m:64 18 (3) 7 0.28
pred dice.merge/3-0 EXIT dice.m:64 18 (3) 7 0.28
@@ -105,7 +105,7 @@
pred dice.main/2-0 <c2;t;> dice.m:22 3 (3) 1 0.25
pred dice.merge_sort/2-0 CALL dice.m:31 3 (3) 1 0.25
pred dice.merge_sort/2-0 EXIT dice.m:31 3 (3) 1 0.25
-mdb> dice -sS -n 1
+mdb> dice -sS -n 1 --module dice
Procedure Path/Port File:Line Pass (3) Fail Suspicion
pred dice.merge/3-0 <s2;c2;s2;c4;e;> dice.m:74 0 (0) 1 1.00
mdb> break dice.m:74
Index: tests/debugger/dice.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/dice.inp,v
retrieving revision 1.1
diff -u -r1.1 dice.inp
--- tests/debugger/dice.inp 10 Feb 2005 04:10:31 -0000 1.1
+++ tests/debugger/dice.inp 10 Feb 2005 04:34:21 -0000
@@ -1,14 +1,14 @@
register --quiet
context none
echo on
-dice -f dice.fail -p dice.passes
+dice -f dice.fail -p dice.passes -m dice
set fail_trace_count dice.fail
set pass_trace_counts dice.passes
-dice -sS
-dice -sSF
-dice -n 3 -s P
-dice -s Fp
-dice -sS -n 1
+dice -sS -m dice
+dice -sSF -m dice
+dice -n 3 -s P -m dice
+dice -s Fp -m dice
+dice -sS -n 1 --module dice
break dice.m:74
c
quit -y
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.193
diff -u -r1.193 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 10 Feb 2005 04:10:33 -0000 1.193
+++ trace/mercury_trace_internal.c 10 Feb 2005 04:29:52 -0000
@@ -615,8 +615,9 @@
const char *item);
static MR_bool MR_trace_options_dice(char **pass_trace_counts_file,
char **fail_trace_count_file, char **sort_str,
- int *number_of_lines, char **out_file, char ***words,
- int *word_count, const char *cat, const char *item);
+ int *number_of_lines, char **out_file, char **module,
+ char ***words, int *word_count, const char *cat,
+ const char *item);
static void MR_trace_usage(const char *cat, const char *item);
static void MR_trace_do_noop(void);
static void MR_mdb_print_proc_id_and_nl(void *data,
@@ -624,7 +625,7 @@
static int MR_trace_var_print_list(MR_Spy_Print_List print_list);
static void MR_trace_print_dice(char *pass_trace_counts_file,
char *fail_trace_counts_file, char *sort_str,
- int number_of_lines, char *out_str);
+ int number_of_lines, char *out_str, char *module);
static const MR_Proc_Layout *MR_find_single_matching_proc(MR_Proc_Spec *spec,
MR_bool verbose);
@@ -5899,6 +5900,7 @@
char *fail_trace_count_file;
char *sort_str = (char*)malloc(MR_MAX_DICE_SORT_STR_SIZE + 1);
char *out_file = NULL;
+ char *module = NULL;
int number_of_lines = MR_DEFAULT_DICE_LINES;
pass_trace_counts_file = MR_dice_pass_trace_counts_file;
@@ -5906,8 +5908,8 @@
strcpy(sort_str, "");
if (! MR_trace_options_dice(&pass_trace_counts_file,
- &fail_trace_count_file, &sort_str, &number_of_lines, &out_file, &words,
- &word_count, "exp", "dice"))
+ &fail_trace_count_file, &sort_str, &number_of_lines, &out_file,
+ &module, &words, &word_count, "exp", "dice"))
{
; /* the usage message has already been printed */
} else if (word_count == 1) {
@@ -5923,7 +5925,7 @@
"command.\n");
} else {
MR_trace_print_dice(pass_trace_counts_file, fail_trace_count_file,
- sort_str, number_of_lines, out_file);
+ sort_str, number_of_lines, out_file, module);
}
} else {
MR_trace_usage("exp", "dice");
@@ -5931,6 +5933,9 @@
free(out_file);
free(sort_str);
+ if (module != NULL) {
+ free(module);
+ }
return KEEP_INTERACTING;
}
@@ -5938,13 +5943,14 @@
static void
MR_trace_print_dice(char *pass_trace_counts_file,
char *fail_trace_count_file, char *sort_str, int number_of_lines,
- char* out_file)
+ char *out_file, char *module)
{
MR_String dice;
MR_String problem;
MR_String aligned_pass_trace_counts_file;
MR_String aligned_fail_trace_count_file;
MR_String aligned_sort_str;
+ MR_String aligned_module;
FILE *fp;
MR_TRACE_USE_HP(
@@ -5953,12 +5959,17 @@
MR_make_aligned_string(aligned_fail_trace_count_file,
(MR_String) fail_trace_count_file);
MR_make_aligned_string(aligned_sort_str, (MR_String) sort_str);
+ if (module == NULL) {
+ MR_make_aligned_string(aligned_module, (MR_String) "");
+ } else {
+ MR_make_aligned_string(aligned_module, (MR_String) module);
+ }
);
MR_TRACE_CALL_MERCURY(
MR_MDB_read_dice_to_string(aligned_pass_trace_counts_file,
- aligned_fail_trace_count_file, aligned_sort_str, number_of_lines,
- &dice, &problem);
+ aligned_fail_trace_count_file, aligned_sort_str,
+ number_of_lines, aligned_module, &dice, &problem);
);
if (MR_streq(problem, "")) {
@@ -7011,18 +7022,20 @@
{ "sort", MR_required_argument, NULL, 's' },
{ "top", MR_required_argument, NULL, 'n' },
{ "output-to-file", MR_required_argument, NULL, 'o' },
+ { "module", MR_required_argument, NULL, 'm' },
{ NULL, MR_no_argument, NULL, 0 }
};
static MR_bool
-MR_trace_options_dice(char** pass_trace_counts_file,
- char** fail_trace_count_file, char** sort_str, int* n, char** out_file,
- char ***words, int *word_count, const char *cat, const char *item)
+MR_trace_options_dice(char **pass_trace_counts_file,
+ char **fail_trace_count_file, char **sort_str, int *n, char **out_file,
+ char **module, char ***words, int *word_count, const char *cat,
+ const char *item)
{
int c;
MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "p:f:s:n:o:",
+ while ((c = MR_getopt_long(*word_count, *words, "p:f:s:n:o:m:",
MR_trace_dice_opts, NULL)) != EOF)
{
switch (c) {
@@ -7072,6 +7085,11 @@
strcpy(*out_file, MR_optarg);
break;
+ case 'm':
+ *module = (char*)malloc(strlen(MR_optarg) + 1);
+ strcpy(*module, MR_optarg);
+ break;
+
default:
MR_trace_usage(cat, item);
return MR_FALSE;
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list