[m-rev.] for review: fix bugs in mdb breakpoint procedure specification
Simon Taylor
stayl at cs.mu.OZ.AU
Mon Feb 11 02:48:46 AEDT 2002
Estimated hours taken: 2.5
Branches: main
Fix bugs in the code to parse and match procedure
specifications for breakpoints:
- handle nested modules.
- handle names containing '/' and '-'.
- use the correct arity for functions, not the arity of the
corresponding predicate.
trace/mercury_trace_tables.c:
Fix the bugs.
runtime/mercury_stack_layout.h:
Add a macro to adjust the arity of functions
recorded in MR_Proc_Layouts for printing.
runtime/mercury_stack_trace.c:
Print the correct arity of functions in stack traces
and debugger events.
tests/debugger/breakpoints.m:
tests/debugger/breakpoints.print_list.m:
tests/debugger/breakpoints.inp:
tests/debugger/breakpoints.exp:
Add test cases.
tests/debugger/existential_type_classes.exp:
tests/debugger/polymorphic_output.exp3:
Update expected output. (I'll update the other output
files after this change is installed).
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.53
diff -u -u -r1.53 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h 10 Dec 2001 06:50:11 -0000 1.53
+++ runtime/mercury_stack_layout.h 10 Feb 2002 13:46:26 -0000
@@ -713,6 +713,11 @@
((MR_EvalMethod) (proc_layout_ptr)-> \
MR_sle_exec_trace.MR_exec_eval_method_CAST_ME)
+ /* Adjust the arity of functions for printing. */
+#define MR_sle_user_adjusted_arity(entry) \
+ ((entry)->MR_sle_user.MR_user_arity - \
+ (((entry)->MR_sle_user.MR_user_pred_or_func == MR_FUNCTION) ? 1 : 0))
+
/*
** Define a layout structure for a procedure, containing information
** for the first two substructures.
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.44
diff -u -u -r1.44 mercury_stack_trace.c
--- runtime/mercury_stack_trace.c 4 Dec 2001 00:44:34 -0000 1.44
+++ runtime/mercury_stack_trace.c 10 Feb 2002 13:46:24 -0000
@@ -980,7 +980,7 @@
fprintf(fp, "%s:%s/%ld-%ld",
entry->MR_sle_user.MR_user_decl_module,
entry->MR_sle_user.MR_user_name,
- (long) entry->MR_sle_user.MR_user_arity,
+ (long) MR_sle_user_adjusted_arity(entry),
(long) entry->MR_sle_user.MR_user_mode);
if (!spec && strcmp(entry->MR_sle_user.MR_user_decl_module,
Index: tests/debugger/breakpoints.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/breakpoints.exp,v
retrieving revision 1.6
diff -u -u -r1.6 breakpoints.exp
--- tests/debugger/breakpoints.exp 25 Sep 2001 09:37:08 -0000 1.6
+++ tests/debugger/breakpoints.exp 10 Feb 2002 15:14:50 -0000
@@ -5,19 +5,19 @@
mdb> break data
Ambiguous procedure specification. The matches are:
0: pred breakpoints:data/1-0 (det)
-1: func breakpoints:data/1-0 (det)
+1: func breakpoints:data/0-0 (det)
Which do you want to put a breakpoint on (0-1 or *)? *
0: + stop interface pred breakpoints:data/1-0 (det)
- 1: + stop interface func breakpoints:data/1-0 (det)
+ 1: + stop interface func breakpoints:data/0-0 (det)
mdb> delete 0
0: E stop interface pred breakpoints:data/1-0 (det)
mdb> delete 1
- 1: E stop interface func breakpoints:data/1-0 (det)
+ 1: E stop interface func breakpoints:data/0-0 (det)
mdb> break data
Ambiguous procedure specification. The matches are:
0: pred breakpoints:data/1-0 (det)
-1: func breakpoints:data/1-0 (det)
+1: func breakpoints:data/0-0 (det)
Which do you want to put a breakpoint on (0-1 or *)? 0
0: + stop interface pred breakpoints:data/1-0 (det)
@@ -35,12 +35,43 @@
3: + stop entry pred breakpoints:qperm/2-0 (nondet)
mdb> break -a qperm
4: + stop all pred breakpoints:qperm/2-0 (nondet)
+mdb> break /
+Ambiguous procedure specification. The matches are:
+0: func breakpoints://2-0 (det)
+1: func breakpoints:print_list://2-0 (det)
+
+Which do you want to put a breakpoint on (0-1 or *)? 0
+ 5: + stop interface func breakpoints://2-0 (det)
+mdb> break //2
+Ambiguous procedure specification. The matches are:
+0: func breakpoints://2-0 (det)
+1: func breakpoints:print_list://2-0 (det)
+
+Which do you want to put a breakpoint on (0-1 or *)? 0
+ 6: + stop interface func breakpoints://2-0 (det)
+mdb> break breakpoints:print_list:-/2
+ 7: + stop interface func breakpoints:print_list:-/2-0 (det)
+mdb> break breakpoints:print_list:--0
+ 8: + stop interface func breakpoints:print_list:-/2-0 (det)
+mdb> break breakpoints__print_list__/-0
+ 9: + stop interface func breakpoints:print_list://2-0 (det)
+mdb> break breakpoints__print_list__print_list
+10: + stop interface pred breakpoints:print_list:print_list/3-0 (det)
+mdb> break breakpoints:print_list:print_list/3
+11: + stop interface pred breakpoints:print_list:print_list/3-0 (det)
mdb> break info
0: - stop interface pred breakpoints:data/1-0 (det)
1: + stop interface pred breakpoints:qperm/2-0 (nondet)
2: + stop interface pred breakpoints:safe/1-0 (semidet)
3: + stop entry pred breakpoints:qperm/2-0 (nondet)
4: + stop all pred breakpoints:qperm/2-0 (nondet)
+ 5: + stop interface func breakpoints://2-0 (det)
+ 6: + stop interface func breakpoints://2-0 (det)
+ 7: + stop interface func breakpoints:print_list:-/2-0 (det)
+ 8: + stop interface func breakpoints:print_list:-/2-0 (det)
+ 9: + stop interface func breakpoints:print_list://2-0 (det)
+10: + stop interface pred breakpoints:print_list:print_list/3-0 (det)
+11: + stop interface pred breakpoints:print_list:print_list/3-0 (det)
mdb> delete 0
0: D stop interface pred breakpoints:data/1-0 (det)
mdb> break info
@@ -48,6 +79,13 @@
2: + stop interface pred breakpoints:safe/1-0 (semidet)
3: + stop entry pred breakpoints:qperm/2-0 (nondet)
4: + stop all pred breakpoints:qperm/2-0 (nondet)
+ 5: + stop interface func breakpoints://2-0 (det)
+ 6: + stop interface func breakpoints://2-0 (det)
+ 7: + stop interface func breakpoints:print_list:-/2-0 (det)
+ 8: + stop interface func breakpoints:print_list:-/2-0 (det)
+ 9: + stop interface func breakpoints:print_list://2-0 (det)
+10: + stop interface pred breakpoints:print_list:print_list/3-0 (det)
+11: + stop interface pred breakpoints:print_list:print_list/3-0 (det)
mdb> disable 3
3: - stop entry pred breakpoints:qperm/2-0 (nondet)
mdb> break nodiag
@@ -74,6 +112,13 @@
2: E stop interface pred breakpoints:safe/1-0 (semidet)
3: D stop entry pred breakpoints:qperm/2-0 (nondet)
4: E stop all pred breakpoints:qperm/2-0 (nondet)
+ 5: E stop interface func breakpoints://2-0 (det)
+ 6: E stop interface func breakpoints://2-0 (det)
+ 7: E stop interface func breakpoints:print_list:-/2-0 (det)
+ 8: E stop interface func breakpoints:print_list:-/2-0 (det)
+ 9: E stop interface func breakpoints:print_list://2-0 (det)
+10: E stop interface pred breakpoints:print_list:print_list/3-0 (det)
+11: E stop interface pred breakpoints:print_list:print_list/3-0 (det)
mdb> break info
There are no break points.
mdb> delete *
Index: tests/debugger/breakpoints.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/breakpoints.inp,v
retrieving revision 1.3
diff -u -u -r1.3 breakpoints.inp
--- tests/debugger/breakpoints.inp 7 Aug 2001 02:16:05 -0000 1.3
+++ tests/debugger/breakpoints.inp 10 Feb 2002 13:59:46 -0000
@@ -13,6 +13,15 @@
break safe
break -e qperm
break -a qperm
+break /
+0
+break //2
+0
+break breakpoints:print_list:-/2
+break breakpoints:print_list:--0
+break breakpoints__print_list__/-0
+break breakpoints__print_list__print_list
+break breakpoints:print_list:print_list/3
break info
delete 0
break info
Index: tests/debugger/breakpoints.m
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/breakpoints.m,v
retrieving revision 1.2
diff -u -u -r1.2 breakpoints.m
--- tests/debugger/breakpoints.m 25 Aug 2000 09:53:35 -0000 1.2
+++ tests/debugger/breakpoints.m 10 Feb 2002 13:58:56 -0000
@@ -6,10 +6,10 @@
:- pred main(io__state, io__state).
:- mode main(di, uo) is cc_multi.
-
+:- func string / string = string.
:- implementation.
-
-:- import_module list, int.
+:- include_module breakpoints__print_list.
+:- import_module list, int, string, breakpoints__print_list.
main -->
( { queen(data, Out) } ->
@@ -76,31 +76,4 @@
D1 is D + 1,
nodiag(B, D1, L).
-:- pred print_list(list(int), io__state, io__state).
-:- mode print_list(in, di, uo) is det.
-
-print_list(Xs) -->
- (
- { Xs = [] }
- ->
- io__write_string("[]\n")
- ;
- io__write_string("["),
- print_list_2(Xs),
- io__write_string("]\n")
- ).
-
-:- pred print_list_2(list(int), io__state, io__state).
-:- mode print_list_2(in, di, uo) is det.
-
-print_list_2([]) --> [].
-print_list_2([X|Xs]) -->
- io__write_int(X),
- (
- { Xs = [] }
- ->
- []
- ;
- io__write_string(", "),
- print_list_2(Xs)
- ).
+X / _ = X.
Index: tests/debugger/breakpoints.print_list.m
===================================================================
RCS file: tests/debugger/breakpoints.print_list.m
diff -N tests/debugger/breakpoints.print_list.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/debugger/breakpoints.print_list.m 10 Feb 2002 12:56:48 -0000
@@ -0,0 +1,42 @@
+:- module breakpoints__print_list.
+
+:- interface.
+
+:- import_module list, io.
+
+:- pred print_list(list(int), io__state, io__state).
+:- mode print_list(in, di, uo) is det.
+
+:- func string / string = string.
+:- func string - string = string.
+
+:- implementation.
+
+print_list(Xs) -->
+ (
+ { Xs = [] }
+ ->
+ io__write_string("[]\n")
+ ;
+ io__write_string("["),
+ print_list_2(Xs),
+ io__write_string("]\n")
+ ).
+
+:- pred print_list_2(list(int), io__state, io__state).
+:- mode print_list_2(in, di, uo) is det.
+
+print_list_2([]) --> [].
+print_list_2([X|Xs]) -->
+ io__write_int(X),
+ (
+ { Xs = [] }
+ ->
+ []
+ ;
+ io__write_string(", "),
+ print_list_2(Xs)
+ ).
+
+Str1 / Str2 = Str1 ++ "/" ++ Str2.
+Str1 - Str2 = Str1 ++ "-" ++ Str2.
Index: tests/debugger/existential_type_classes.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/existential_type_classes.exp,v
retrieving revision 1.10
diff -u -u -r1.10 existential_type_classes.exp
--- tests/debugger/existential_type_classes.exp 3 Jul 2001 02:49:26 -0000 1.10
+++ tests/debugger/existential_type_classes.exp 10 Feb 2002 15:17:42 -0000
@@ -68,9 +68,9 @@
HeadVar__2 4
mdb> continue -a
18: 10 2 CALL existential_type_classes.m:74 (from existential_type_classes.m:53)
- func existential_type_classes:my_exist_t/1-0 (det)
+ func existential_type_classes:my_exist_t/0-0 (det)
19: 10 2 EXIT existential_type_classes.m:74 (from existential_type_classes.m:53)
- func existential_type_classes:my_exist_t/1-0 (det)
+ func existential_type_classes:my_exist_t/0-0 (det)
20: 11 2 CALL existential_type_classes.m:68 (from existential_type_classes.m:53)
pred existential_type_classes:do_foo/2-0 (det)
mdb> P
@@ -101,13 +101,13 @@
HeadVar__2 86
mdb> continue -a
28: 15 2 CALL existential_type_classes.m:70 (from existential_type_classes.m:54)
- func existential_type_classes:call_my_exist_t/1-0 (det)
+ func existential_type_classes:call_my_exist_t/0-0 (det)
29: 16 3 CALL existential_type_classes.m:74 (from existential_type_classes.m:70)
- func existential_type_classes:my_exist_t/1-0 (det)
+ func existential_type_classes:my_exist_t/0-0 (det)
30: 16 3 EXIT existential_type_classes.m:74 (from existential_type_classes.m:70)
- func existential_type_classes:my_exist_t/1-0 (det)
+ func existential_type_classes:my_exist_t/0-0 (det)
31: 15 2 EXIT existential_type_classes.m:70 (from existential_type_classes.m:54)
- func existential_type_classes:call_my_exist_t/1-0 (det)
+ func existential_type_classes:call_my_exist_t/0-0 (det)
32: 17 2 CALL existential_type_classes.m:68 (from existential_type_classes.m:54)
pred existential_type_classes:do_foo/2-0 (det)
mdb> P
@@ -138,13 +138,13 @@
HeadVar__2 86
mdb> continue -a
40: 21 2 CALL existential_type_classes.m:82 (from existential_type_classes.m:55)
- func existential_type_classes:my_univ/2-0 (det)
+ func existential_type_classes:my_univ/1-0 (det)
41: 21 2 EXIT existential_type_classes.m:82 (from existential_type_classes.m:55)
- func existential_type_classes:my_univ/2-0 (det)
+ func existential_type_classes:my_univ/1-0 (det)
42: 22 2 CALL existential_type_classes.m:76 (from existential_type_classes.m:55)
- func existential_type_classes:my_univ_value/2-0 (det)
+ func existential_type_classes:my_univ_value/1-0 (det)
43: 22 2 EXIT existential_type_classes.m:76 (from existential_type_classes.m:55)
- func existential_type_classes:my_univ_value/2-0 (det)
+ func existential_type_classes:my_univ_value/1-0 (det)
44: 23 2 CALL existential_type_classes.m:68 (from existential_type_classes.m:55)
pred existential_type_classes:do_foo/2-0 (det)
mdb> P
@@ -175,25 +175,25 @@
HeadVar__2 90
mdb>
52: 27 2 CALL existential_type_classes.m:82 (from existential_type_classes.m:56)
- func existential_type_classes:my_univ/2-0 (det)
+ func existential_type_classes:my_univ/1-0 (det)
mdb>
53: 27 2 EXIT existential_type_classes.m:82 (from existential_type_classes.m:56)
- func existential_type_classes:my_univ/2-0 (det)
+ func existential_type_classes:my_univ/1-0 (det)
mdb>
54: 28 2 CALL existential_type_classes.m:72 (from existential_type_classes.m:56)
- func existential_type_classes:call_my_univ_value/2-0 (det)
+ func existential_type_classes:call_my_univ_value/1-0 (det)
mdb> P
HeadVar__1 my_univ('<<c_pointer>>')
mdb>
55: 29 3 CALL existential_type_classes.m:76 (from existential_type_classes.m:72)
- func existential_type_classes:my_univ_value/2-0 (det)
+ func existential_type_classes:my_univ_value/1-0 (det)
mdb> P
Univ my_univ('<<c_pointer>>')
mdb> continue -a
56: 29 3 EXIT existential_type_classes.m:76 (from existential_type_classes.m:72)
- func existential_type_classes:my_univ_value/2-0 (det)
+ func existential_type_classes:my_univ_value/1-0 (det)
57: 28 2 EXIT existential_type_classes.m:72 (from existential_type_classes.m:56)
- func existential_type_classes:call_my_univ_value/2-0 (det)
+ func existential_type_classes:call_my_univ_value/1-0 (det)
58: 30 2 CALL existential_type_classes.m:68 (from existential_type_classes.m:56)
pred existential_type_classes:do_foo/2-0 (det)
mdb> P
Index: tests/debugger/polymorphic_output.exp3
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/polymorphic_output.exp3,v
retrieving revision 1.5
diff -u -u -r1.5 polymorphic_output.exp3
--- tests/debugger/polymorphic_output.exp3 4 Feb 2002 05:23:02 -0000 1.5
+++ tests/debugger/polymorphic_output.exp3 10 Feb 2002 15:18:53 -0000
@@ -5,11 +5,11 @@
mdb> context none
Contexts will not be printed.
mdb> b functor_names
- 0: + stop interface func polymorphic_output:functor_names/2-0 (det)
+ 0: + stop interface func polymorphic_output:functor_names/1-0 (det)
mdb> c
- 2: 2 2 CALL func polymorphic_output:functor_names/2-0 (det)
+ 2: 2 2 CALL func polymorphic_output:functor_names/1-0 (det)
mdb> delete 0
- 0: E stop interface func polymorphic_output:functor_names/2-0 (det)
+ 0: E stop interface func polymorphic_output:functor_names/1-0 (det)
mdb> p goal
functor_names(two("three", 3, three("four", 4, "one", 1, empty, empty, empty), two("two", 2, empty, empty))) = _
mdb> set format verbose
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.18
diff -u -u -r1.18 mercury_trace_tables.c
--- trace/mercury_trace_tables.c 15 Jun 2001 04:46:25 -0000 1.18
+++ trace/mercury_trace_tables.c 10 Feb 2002 15:30:38 -0000
@@ -39,6 +39,8 @@
*file_layout, int line,
MR_file_line_callback callback_func, int callback_arg);
+static bool MR_parse_trailing_number(char *str, char **s, int *n);
+
void
MR_register_all_modules_and_procs(FILE *fp, bool verbose)
{
@@ -218,9 +220,11 @@
MR_parse_proc_spec(char *str, MR_Proc_Spec *spec)
{
char *dash;
- char *slash;
- char *s;
+ char *start;
+ char *end;
int n;
+ int len;
+ int double_underscores;
bool found;
spec->MR_proc_module = NULL;
@@ -229,6 +233,50 @@
spec->MR_proc_mode = -1;
spec->MR_proc_pf = (MR_PredFunc) -1;
+ len = strlen(str);
+
+ /*
+ ** Check for the optional trailing arity and mode number.
+ ** This also checks for filename:linenumber breakpoint specifiers.
+ */
+ end = str + len - 1;
+ if (MR_parse_trailing_number(str, &end, &n)) {
+ if (end < str) {
+ /* the string contains only a number */
+ return FALSE;
+ }
+ if (*end == ':') {
+ /* filename:linenumber */
+ return FALSE;
+ } else if (*end == '-') {
+ spec->MR_proc_mode = n;
+
+ /*
+ ** Avoid modifying the string until we're sure
+ ** the parse can't fail.
+ */
+ dash = end;
+
+ end--;
+ if (MR_parse_trailing_number(str, &end, &n)) {
+ if (end < str) {
+ /* the string contains only a number */
+ return FALSE;
+ }
+ if (*end == '/') {
+ *end = '\0';
+ spec->MR_proc_arity = n;
+ end--;
+ }
+ }
+ *dash = '\0';
+ } else if (*end == '/') {
+ *end = '\0';
+ end--;
+ spec->MR_proc_arity = n;
+ }
+ }
+
if (strneq(str, "pred*", 5)) {
spec->MR_proc_pf = MR_PREDICATE;
str += 5;
@@ -237,79 +285,59 @@
str += 5;
}
- if ((dash = strrchr(str, '-')) != NULL) {
- found = FALSE;
- n = 0;
- for (s = dash + 1; *s != '\0'; s++) {
- if (MR_isdigit(*s)) {
- found = TRUE;
- n = n * 10 + *s - '0';
+ /* Search backwards for the end of the final module qualifier. */
+ while (end >= str) {
+ if (*end == ':' || (*end == '_' && *(end + 1) == '_')) {
+ if (*end == ':') {
+ spec->MR_proc_name = end + 1;
} else {
- /* a dash followed by a nondigit is an error */
- return FALSE;
+ spec->MR_proc_name = end + 2;
}
- }
-
- if (! found) {
- /* a dash with no following digit is an error */
- return FALSE;
- }
- spec->MR_proc_mode = n;
- *dash = '\0';
- }
-
- if ((slash = strrchr(str, '/')) != NULL) {
- found = FALSE;
- n = 0;
- for (s = slash + 1; *s != '\0'; s++) {
- if (MR_isdigit(*s)) {
- found = TRUE;
- n = n * 10 + *s - '0';
- } else {
- /* a slash followed by a nondigit is an error */
- return FALSE;
+ /*
+ ** Convert all occurences of '__' to ':'.
+ */
+ double_underscores = 0;
+ for (start = str; start < end; start++) {
+ if (*start == '_' && *(start + 1) == '_') {
+ *(start - double_underscores) = ':';
+ double_underscores++;
+ start++;
+ } else {
+ *(start - double_underscores) = *start;
+ }
}
- }
+ *(end - double_underscores) = '\0';
- if (! found) {
- /* a slash with no following digit is an error */
- return FALSE;
- }
-
- spec->MR_proc_arity = n;
- *slash = '\0';
- }
-
- if (MR_isdigit(*str)) {
- /* this looks to be a line number */
- return FALSE;
- }
-
- for (s = str; *s != '\0'; s++) {
- if (*s == ':' && MR_isdigit(*(s+1))) {
- /* this looks to be filename:linenumber */
- return FALSE;
- }
-
- if (*s == ':' || (*s == '_' && *(s+1) == '_')) {
- if (*s == ':') {
- spec->MR_proc_name = s+1;
- } else {
- spec->MR_proc_name = s+2;
- }
-
- *s = '\0';
spec->MR_proc_module = str;
return TRUE;
+ } else {
+ end--;
}
}
+ /* There was no module qualifier. */
spec->MR_proc_name = str;
return TRUE;
}
+static bool
+MR_parse_trailing_number(char *start, char **end, int *n)
+{
+ bool found_digit = FALSE;
+ int power_of_10 = 1;
+
+ *n = 0;
+ while (*end >= start && MR_isdigit(**end)) {
+ found_digit = TRUE;
+ *n += power_of_10 * (**end - '0');
+ power_of_10 *= 10;
+ (*end)--;
+ }
+ return found_digit;
+}
+
#define MR_INIT_MATCH_PROC_SIZE 8
static void
@@ -398,8 +426,8 @@
cur->MR_sle_user.MR_user_name))
#define match_arity(spec, cur) (((spec)->MR_proc_arity < 0) || \
- (spec)->MR_proc_arity == \
- cur->MR_sle_user.MR_user_arity)
+ (spec)->MR_proc_arity == \
+ MR_sle_user_adjusted_arity(cur))
#define match_mode(spec, cur) (((spec)->MR_proc_mode < 0) || \
(spec)->MR_proc_mode == \
--------------------------------------------------------------------------
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