[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