[m-rev.] for review: mdb: break proc_spec port_name

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Jun 12 11:12:10 AEST 2007


For review by anyone.

Zoltan.

Satisfy a request by Peter Ross: give mdb users the ability to specify
exactly which events inside a procedure they want to put breakpoints on.
Amongst other things, this can make checking postconditions easier:
you can now put a conditional breakpoint on only the exit event.

runtime/mercury_stack_layout.h:
	Add fields to the exec trace part of proc layouts an array of the
	label layouts describing the events of the procedure. This is the
	most direct way to implement the new functionality. (In theory,
	we could search the data structures that map file names and line
	numbers to label layouts, but that would be complex, inefficient,
	and *error prone*.)

	To make room for the new fields, and to prepare for making the
	procedure body available to the deep profiler as well (which could
	use it to map execution frequencies of calls back to their location
	in the procedure body, and thus to things like the frequencies with
	which various switch arms are selected), move the procedure body
	of the execution-trace-specific part of the proc layout, and to
	where the deep profiler could in the future also get at it.

runtime/mercury_goto.h:
	Add macros for declaring more than one label layout structure at a
	time.

compiler/layout.m:
	Implement the changes in mercury_stack_layout.h in the compiler's
	data structures as well.

compiler/stack_layout.m:
	Conform to the changes in mercury_stack_layout.h.

	Turn some tuples into named types.

compiler/layout_out.m:
	Conform to the changes in mercury_stack_layout.h.

	Add a mechanism to declare the label layouts in the new array before
	referring to them, by generalizing some existing code. Make this code
	require that the label layouts we refer to via the macros in
	mercury_goto.h match the declarations generated by those macros,
	i.e. that they have information about variables (if debugging is
	enabled, they will).

compiler/opt_debug.m:
	Conform to the change to layout.m.

compiler/prog_rep.m:
	Make a predicate name more expressive.

trace/mercury_trace_cmd_breakpoint.c:
	Implement the new way of using the "break" command, which is
	to add a port name after the procedure specification.

	Register procedures at the start of the function implementing
	the "break" command, instead of "on demand", since all alternatives
	eventually do demand it.

	Write ambiguity reports wholly to mdb's stdout, instead of partially to
	stderr and partially to stdout.

trace/mercury_trace_spy.c:
	Print the port and the goal path for breakpoints on specific events.

	Make the invocation conditions left-aligned, not right-aligned.

doc/user_guide.texi:
	Document the new way of using the "break" command.

NEWS:
	Announce the new capability.

tests/queens.{inp,exp,exp2}:
	Add tests of the new capability.

tests/breakpoints.{exp,exp}:
tests/lval_desc_array.{exp,exp2}:
	Expect the new alignment of invocation conditions.

cvs diff: Diffing .
Index: NEWS
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/NEWS,v
retrieving revision 1.465
diff -u -r1.465 NEWS
--- NEWS	7 Jun 2007 06:53:50 -0000	1.465
+++ NEWS	12 Jun 2007 00:00:14 -0000
@@ -211,6 +211,8 @@
 
 * The `dd' command now accepts a `--reset-knowledge-base' option.
 
+* You can now put breakpoints on individual events inside procedures.
+
 DETAILED LISTING
 ================
 
@@ -297,6 +299,12 @@
   This option resets the declarative debugger's knowledge base of previous
   question answers.
 
+* You can now put breakpoints on individual events inside procedures.
+  Commands of the form "break <procedure-specification> <portname>"
+  will cause execution to stop only at the specified port in the specified
+  procedure. If there is more than event of the given port type in the
+  procedure, mdb will prompt the user to select one.
+
 NEWS for Mercury 0.13.1
 -----------------------
 
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.35
diff -u -r1.35 layout.m
--- compiler/layout.m	18 Mar 2007 23:34:52 -0000	1.35
+++ compiler/layout.m	11 Jun 2007 02:09:09 -0000
@@ -161,16 +161,21 @@
 :- type maybe_proc_id_and_more
     --->    no_proc_id
     ;       proc_id(
-                maybe(proc_layout_proc_static),
-                maybe(proc_layout_exec_trace)
+                maybe_proc_static       :: maybe(proc_layout_proc_static),
+                maybe_exec_trace        :: maybe(proc_layout_exec_trace),
+                proc_body_bytes         :: list(int)
+                                        % The procedure body represented as
+                                        % a list of bytecodes.
             ).
 
 :- type proc_layout_exec_trace          % defines MR_ExecTrace
     --->    proc_layout_exec_trace(
                 maybe_call_label_layout :: maybe(label_layout_details),
-                proc_body_bytes         :: list(int),
-                                        % The procedure body represented as
-                                        % a list of bytecodes.
+
+                proc_label_layouts      :: list(data_addr),
+                                        % The label layouts of the events in
+                                        % the predicate. Interface events
+                                        % first, internal events second.
 
                 maybe_table_info        :: maybe(data_addr),
                 head_var_nums           :: list(int),
@@ -213,6 +218,7 @@
             % A proc layout structure for stack tracing, accurate gc,
             % deep profiling and/or execution tracing.
     ;       proc_layout_exec_trace(rtti_proc_label)
+    ;       proc_layout_label_layouts(rtti_proc_label)
     ;       proc_layout_head_var_nums(rtti_proc_label)
             % A vector of variable numbers, containing the numbers of the
             % procedure's head variables, including the ones generated by
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.91
diff -u -r1.91 layout_out.m
--- compiler/layout_out.m	23 May 2007 10:09:17 -0000	1.91
+++ compiler/layout_out.m	11 Jun 2007 02:32:10 -0000
@@ -269,6 +269,12 @@
         output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
             !IO)
     ;
+        Data = proc_layout_label_layouts(RttiProcLabel),
+        io.write_string(mercury_data_prefix, !IO),
+        io.write_string("_proc_label_layouts__", !IO),
+        output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
+            !IO)
+    ;
         Data = proc_layout_head_var_nums(RttiProcLabel),
         io.write_string(mercury_data_prefix, !IO),
         io.write_string("_head_var_nums__", !IO),
@@ -467,6 +473,11 @@
         io.write_string("static MR_STATIC_CODE_CONST MR_ExecTrace\n\t", !IO),
         output_layout_name(Name, !IO)
     ;
+        Name = proc_layout_label_layouts(_ProcLabel),
+        io.write_string("static const MR_LabelLayout *", !IO),
+        output_layout_name(Name, !IO),
+        io.write_string("[]", !IO)
+    ;
         Name = proc_layout_head_var_nums(_ProcLabel),
         io.write_string("static const ", !IO),
         io.write_string("MR_uint_least16_t ", !IO),
@@ -592,6 +603,7 @@
 layout_name_would_include_code_addr(user_event_attr_var_nums(_, _)) = no.
 layout_name_would_include_code_addr(proc_layout(_, _)) = no.
 layout_name_would_include_code_addr(proc_layout_exec_trace(_)) = yes.
+layout_name_would_include_code_addr(proc_layout_label_layouts(_)) = no.
 layout_name_would_include_code_addr(proc_layout_head_var_nums(_)) = no.
 layout_name_would_include_code_addr(proc_layout_var_names(_)) = no.
 layout_name_would_include_code_addr(proc_layout_body_bytecode(_)) = no.
@@ -855,7 +867,7 @@
         output_layout_no_proc_id_group(!IO),
         output_proc_layout_data_defn_end(!IO)
     ;
-        MaybeRest = proc_id(MaybeProcStatic, MaybeExecTrace),
+        MaybeRest = proc_id(MaybeProcStatic, MaybeExecTrace, ProcBodyBytes),
         (
             MaybeProcStatic = yes(ProcStatic),
             output_proc_static_data_defn(RttiProcLabel, ProcStatic, !DeclSet,
@@ -878,6 +890,17 @@
         ;
             MaybeExecTrace = no
         ),
+        (
+            ProcBodyBytes = []
+        ;
+            ProcBodyBytes = [_ | _],
+            io.write_string("\n", !IO),
+            output_layout_name_storage_type_name(
+                proc_layout_body_bytecode(RttiProcLabel), yes, !IO),
+            io.write_string(" = {\n", !IO),
+            output_bytecodes_driver(ProcBodyBytes, !IO),
+            io.write_string("};\n\n", !IO)
+        ),
 
         output_proc_layout_data_defn_start(RttiProcLabel, Kind, Traversal,
             !IO),
@@ -894,11 +917,19 @@
         ),
         (
             MaybeProcStatic = no,
-            io.write_string("NULL\n", !IO)
+            io.write_string("NULL,\n", !IO)
         ;
             MaybeProcStatic = yes(_),
             io.write_string("&", !IO),
             output_layout_name(proc_static(RttiProcLabel), !IO),
+            io.write_string(",\n", !IO)
+        ),
+        (
+            ProcBodyBytes = [],
+            io.write_string("NULL\n", !IO)
+        ;
+            ProcBodyBytes = [_ | _],
+            output_layout_name(proc_layout_body_bytecode(RttiProcLabel), !IO),
             io.write_string("\n", !IO)
         ),
         output_proc_layout_data_defn_end(!IO)
@@ -914,7 +945,7 @@
         MaybeRest = no_proc_id,
         Kind = proc_layout_traversal
     ;
-        MaybeRest = proc_id(_, _),
+        MaybeRest = proc_id(_, _, _),
         Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel))
     ).
 
@@ -1009,13 +1040,17 @@
     io::di, io::uo) is det.
 
 output_layout_exec_trace_decls(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
-    ExecTrace = proc_layout_exec_trace(MaybeCallLabelLayout, _ProcBodyBytes,
-        MaybeTableInfo, _HeadVarNums, _VarNames, _MaxVarNum,
+    ExecTrace = proc_layout_exec_trace(MaybeCallLabelLayout,
+        EventDataAddrs, MaybeTableInfo, _HeadVarNums, _VarNames, _MaxVarNum,
         _MaxRegNum, _MaybeFromFullSlot, _MaybeIoSeqSlot,
         _MaybeTrailSlot, _MaybeMaxfrSlot, _EvalMethod,
         _MaybeCallTableSlot, _EffTraceLevel, _Flags),
     ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
     ModuleName = get_defining_module_name(ProcLabel),
+    output_label_layout_addrs_in_vector(EventDataAddrs, "MR_DECL_LABEL_LAYOUT",
+        !IO),
+    EventDataDeclIds = list.map(wrap_decl_data_addr, EventDataAddrs),
+    list.foldl(decl_set_insert, EventDataDeclIds, !DeclSet),
     (
         MaybeCallLabelLayout = yes(CallLabelDetails),
         CallLabelDetails = label_layout_details(CallProcLabel, LabelNum,
@@ -1033,6 +1068,10 @@
         MaybeTableInfo = no
     ).
 
+:- func wrap_decl_data_addr(data_addr) = decl_id.
+
+wrap_decl_data_addr(DataAddr) = decl_data_addr(DataAddr).
+
     % The job of this predicate is to minimize stack space consumption in
     % grades that do not allow output_bytecodes to be tail recursive.
     %
@@ -1076,22 +1115,24 @@
     io::di, io::uo) is det.
 
 output_layout_exec_trace(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
-    ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails, ProcBodyBytes,
-        MaybeTableInfo, HeadVarNums, _VarNames, MaxVarNum,
+    ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails,
+        EventDataAddrs, MaybeTableInfo, HeadVarNums, _VarNames, MaxVarNum,
         MaxRegNum, MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
         MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot, EffTraceLevel, Flags),
+
     (
-        ProcBodyBytes = []
+        EventDataAddrs = []
     ;
-        ProcBodyBytes = [_ | _],
+        EventDataAddrs = [_ | _],
         io.write_string("\n", !IO),
         output_layout_name_storage_type_name(
-            proc_layout_body_bytecode(RttiProcLabel), yes, !IO),
+            proc_layout_label_layouts(RttiProcLabel), yes, !IO),
         io.write_string(" = {\n", !IO),
-        output_bytecodes_driver(ProcBodyBytes, !IO),
-        io.write_string("};\n", !IO)
+        output_label_layout_addrs_in_vector(EventDataAddrs, "MR_LABEL_LAYOUT",
+            !IO),
+        io.write_string("};\n\n", !IO)
     ),
-    io.write_string("\n", !IO),
+
     output_layout_name_storage_type_name(
         proc_layout_exec_trace(RttiProcLabel), yes, !IO),
     io.write_string(" = {\n", !IO),
@@ -1112,14 +1153,17 @@
     output_layout_name(module_layout(ModuleName), !IO),
     io.write_string(",\n", !IO),
     (
-        ProcBodyBytes = [],
-        io.write_string("NULL", !IO)
+        EventDataAddrs = [],
+        io.write_string("NULL,\n", !IO)
     ;
-        ProcBodyBytes = [_ | _],
-        output_layout_name(proc_layout_body_bytecode(RttiProcLabel), !IO)
+        EventDataAddrs = [_ | _],
+        output_layout_name(proc_layout_label_layouts(RttiProcLabel), !IO),
+        io.write_string(",\n", !IO)
     ),
+    list.length(EventDataAddrs, NumEventDataAddrs),
+    io.write_int(NumEventDataAddrs, !IO),
     io.write_string(",\n", !IO),
-    io.write_string("0,\n{ ", !IO),
+    io.write_string("{ ", !IO),
     (
         MaybeTableInfo = yes(TableInfo),
         io.write_string("(const void *) &", !IO),
@@ -1895,67 +1939,71 @@
         io.write_string("NULL\n", !IO)
     ;
         LabelAddrs = [_ | _],
-        list.map(project_label_layout, LabelAddrs, Labels),
-        output_label_layout_addrs_in_vector(Labels, !IO)
+        output_label_layout_addrs_in_vector(LabelAddrs, "MR_LABEL_LAYOUT", !IO)
     ),
     io.write_string("};\n", !IO),
     decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
 
-:- pred project_label_layout(data_addr::in, label::out) is det.
+%-----------------------------------------------------------------------------%
 
-project_label_layout(DataAddr, Label) :-
+:- pred output_label_layout_addrs_in_vector(list(data_addr)::in, string::in,
+    io::di, io::uo) is det.
+
+output_label_layout_addrs_in_vector([], _, !IO).
+output_label_layout_addrs_in_vector([DataAddr | DataAddrs], Macro, !IO) :-
     (
         DataAddr = layout_addr(LayoutName),
-        LayoutName = label_layout(ProcLabel, LabelNum, _)
+        LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info)
     ->
-        Label = internal_label(LabelNum, ProcLabel)
-    ;
-        unexpected(this_file, "project_label_layout: not label layout")
-    ).
-
-:- pred output_label_layout_addrs_in_vector(list(label)::in, io::di, io::uo)
-    is det.
-
-output_label_layout_addrs_in_vector([], !IO).
-output_label_layout_addrs_in_vector([Label | Labels], !IO) :-
-    (
-        Label = internal_label(LabelNum, ProcLabel),
         groupable_labels(ProcLabel, 1, _N, [LabelNum], RevLabelNums,
-            Labels, RemainingLabels)
-    ->
+            DataAddrs, RemainingDataAddrs),
         list.reverse(RevLabelNums, LabelNums),
-        io.write_string("MR_LABEL_LAYOUT", !IO),
+        io.write_string(Macro, !IO),
         io.write_int(list.length(LabelNums), !IO),
         io.write_string("(", !IO),
         output_proc_label_no_prefix(ProcLabel, !IO),
         io.write_string(",", !IO),
         io.write_list(LabelNums, ",", io.write_int, !IO),
         io.write_string(")\n", !IO),
-        output_label_layout_addrs_in_vector(RemainingLabels, !IO)
+        output_label_layout_addrs_in_vector(RemainingDataAddrs, Macro, !IO)
     ;
-        io.write_string("MR_LABEL_LAYOUT(", !IO),
-        output_label(Label, !IO),
-        io.write_string("),\n", !IO),
-        output_label_layout_addrs_in_vector(Labels, !IO)
+        unexpected(this_file,
+            "output_label_layout_addrs_in_vector: not label layout")
     ).
 
 :- pred groupable_labels(proc_label::in, int::in, int::out,
-    list(int)::in, list(int)::out, list(label)::in, list(label)::out) is det.
+    list(int)::in, list(int)::out, list(data_addr)::in, list(data_addr)::out)
+    is det.
 
-groupable_labels(ProcLabel, !Count, !RevLabelsNums, !Labels) :-
+groupable_labels(GroupProcLabel, !Count, !RevLabelsNums, !DataAddrs) :-
     (
-        % There must be a macro of the form MR_LABEL_LAYOUT<n>
-        % for every <n> up to MaxChunkSize.
-        !.Labels = [Label | !:Labels],
-        MaxChunkSize = 9,
-        !.Count < MaxChunkSize, % leave room for the one we're adding
-        Label = internal_label(LabelNum, ProcLabel)
-    ->
-        !:Count = !.Count + 1,
-        !:RevLabelsNums = [LabelNum | !.RevLabelsNums],
-        groupable_labels(ProcLabel, !Count, !RevLabelsNums, !Labels)
+        !.DataAddrs = []
     ;
-        true
+        !.DataAddrs = [DataAddr | DataAddrsTail],
+        (
+            DataAddr = layout_addr(LayoutName),
+            LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info)
+        ->
+            % There must be a macro of the form MR_LABEL_LAYOUT<n> and
+            % MR_DECL_LABEL_LAYOUT<n> for every <n> up to MaxChunkSize.
+            MaxChunkSize = 9,
+            (
+                % We cannot group together labels from different procedures.
+                ProcLabel = GroupProcLabel,
+                % Leave room for the one we're adding.
+                !.Count < MaxChunkSize
+            ->
+                !:DataAddrs = DataAddrsTail,
+                !:Count = !.Count + 1,
+                !:RevLabelsNums = [LabelNum | !.RevLabelsNums],
+                groupable_labels(GroupProcLabel, !Count, !RevLabelsNums,
+                    !DataAddrs)
+            ;
+                true
+            )
+        ;
+            unexpected(this_file, "groupable_labels: not label layout")
+        )
     ).
 
 %-----------------------------------------------------------------------------%
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.308
diff -u -r1.308 llds_out.m
--- compiler/llds_out.m	8 Jun 2007 04:31:19 -0000	1.308
+++ compiler/llds_out.m	11 Jun 2007 02:17:12 -0000
@@ -663,7 +663,7 @@
 output_write_proc_static_list_decls([Data | Datas], !DeclSet, !IO) :-
     (
         Data = proc_layout_data(_, _, MaybeRest),
-        MaybeRest = proc_id(yes(_), _)
+        MaybeRest = proc_id(yes(_), _, _)
     ->
         output_maybe_layout_data_decl(Data, !DeclSet, !IO)
     ;
@@ -678,7 +678,7 @@
 output_write_proc_static_list([Data | Datas], !IO) :-
     (
         Data = proc_layout_data(RttiProcLabel, _, MaybeRest),
-        MaybeRest = proc_id(yes(_), _)
+        MaybeRest = proc_id(yes(_), _, _)
     ->
         ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
         UserOrUCI = proc_label_user_or_uci(ProcLabel),
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.192
diff -u -r1.192 opt_debug.m
--- compiler/opt_debug.m	18 Mar 2007 23:34:56 -0000	1.192
+++ compiler/opt_debug.m	6 Jun 2007 07:58:54 -0000
@@ -453,6 +453,8 @@
     "proc_layout(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
 dump_layout_name(proc_layout_exec_trace(RttiProcLabel)) =
     "proc_layout_exec_trace(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
+dump_layout_name(proc_layout_label_layouts(RttiProcLabel)) =
+    "proc_layout_label_layouts(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
 dump_layout_name(proc_layout_head_var_nums(RttiProcLabel)) =
     "proc_layout_head_var_nums(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
 dump_layout_name(proc_layout_var_names(RttiProcLabel)) =
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.52
diff -u -r1.52 prog_rep.m
--- compiler/prog_rep.m	6 Jan 2007 09:23:49 -0000	1.52
+++ compiler/prog_rep.m	11 Jun 2007 02:28:09 -0000
@@ -44,7 +44,7 @@
     %
 :- type var_num_map == map(prog_var, pair(int, string)).
 
-:- pred represent_proc(list(prog_var)::in, hlds_goal::in, 
+:- pred represent_proc_as_bytecodes(list(prog_var)::in, hlds_goal::in, 
     instmap::in, vartypes::in, var_num_map::in, module_info::in,
     stack_layout_info::in, stack_layout_info::out, list(int)::out) is det.
 
@@ -80,7 +80,7 @@
                 module_info :: module_info
             ).
 
-represent_proc(HeadVars, Goal, InstMap0, VarTypes, VarNumMap,
+represent_proc_as_bytecodes(HeadVars, Goal, InstMap0, VarTypes, VarNumMap,
         ModuleInfo, !StackInfo, ProcRepBytes) :-
     Goal = hlds_goal(_, GoalInfo),
     goal_info_get_context(GoalInfo, Context),
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.134
diff -u -r1.134 stack_layout.m
--- compiler/stack_layout.m	18 Mar 2007 23:34:56 -0000	1.134
+++ compiler/stack_layout.m	11 Jun 2007 02:28:10 -0000
@@ -5,10 +5,10 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %---------------------------------------------------------------------------%
-% 
+%
 % File: stack_layout.m.
 % Main authors: trd, zs.
-% 
+%
 % This module generates label, procedure, module and closure layout structures
 % for code in the current module for the LLDS backend. Layout structures are
 % used by the parts of the runtime system that need to look at the stacks
@@ -24,7 +24,7 @@
 % runtime/mercury_stack_layout.h.
 %
 % TODO: Handle the parent_sp register and parent stack variables.
-% 
+%
 %---------------------------------------------------------------------------%
 
 :- module ll_backend.stack_layout.
@@ -276,10 +276,9 @@
 
 %---------------------------------------------------------------------------%
 
-    % Construct the layouts that concern a single procedure:
-    % the procedure-specific layout and the layouts of the labels
-    % inside that procedure. Also update the module-wide label table
-    % with the labels defined in this procedure.
+    % Construct the layouts that concern a single procedure: the procedure
+    % layout and the layouts of the labels inside that procedure. Also update
+    % the module-wide label table with the labels defined in this procedure.
     %
 :- pred construct_layouts(proc_layout_info::in,
     stack_layout_info::in, stack_layout_info::out) is det.
@@ -331,26 +330,35 @@
     ->
         list.map_foldl(
             construct_internal_layout(ProcLabel, ProcLayoutName, VarNumMap),
-            Internals, InternalLayouts, !Info)
+            Internals, InternalLabelInfos, !Info)
     ;
-        InternalLayouts = []
+        InternalLabelInfos = []
     ),
     get_label_tables(!.Info, LabelTables0),
-    list.foldl(update_label_table, InternalLayouts,
+    list.foldl(update_label_table, InternalLabelInfos,
         LabelTables0, LabelTables),
     set_label_tables(LabelTables, !Info),
-    construct_proc_layout(ProcLayoutInfo, Kind, VarNumMap, !Info).
+    construct_proc_layout(ProcLayoutInfo, InternalLabelInfos, Kind, VarNumMap,
+        !Info).
 
 %---------------------------------------------------------------------------%
 
+:- type internal_label_info
+    --->    internal_label_info(
+                containing_proc         :: proc_label,
+                label_num_in_proc       :: int,
+                maybe_has_var_info      :: label_vars,
+                internal_layout_info    :: internal_layout_info
+            ).
+
     % Add the given label layout to the module-wide label tables.
     %
-:- pred update_label_table(
-    {proc_label, int, label_vars, internal_layout_info}::in,
+:- pred update_label_table(internal_label_info::in,
     map(string, label_table)::in, map(string, label_table)::out) is det.
 
-update_label_table({ProcLabel, LabelNum, LabelVars, InternalInfo},
-        !LabelTables) :-
+update_label_table(InternalLabelInfo, !LabelTables) :-
+    InternalLabelInfo = internal_label_info(ProcLabel, LabelNum, LabelVars,
+        InternalInfo),
     InternalInfo = internal_layout_info(Port, _, Return),
     (
         Return = yes(return_layout_info(TargetsContexts, _)),
@@ -361,8 +369,8 @@
         ;
             IsReturn = unknown_callee
         ),
-        update_label_table_2(ProcLabel, LabelNum,
-            LabelVars, Context, IsReturn, !LabelTables)
+        update_label_table_2(ProcLabel, LabelNum, LabelVars, Context,
+            IsReturn, !LabelTables)
     ;
         Port = yes(trace_port_layout_info(Context, _, _, _, _, _)),
         context_is_valid(Context)
@@ -482,10 +490,11 @@
     % Construct a procedure-specific layout.
     %
 :- pred construct_proc_layout(proc_layout_info::in,
-    proc_layout_kind::in, var_num_map::in,
+    list(internal_label_info)::in, proc_layout_kind::in, var_num_map::in,
     stack_layout_info::in, stack_layout_info::out) is det.
 
-construct_proc_layout(ProcLayoutInfo, Kind, VarNumMap, !Info) :-
+construct_proc_layout(ProcLayoutInfo, InternalLabelInfos, Kind, VarNumMap,
+        !Info) :-
     ProcLayoutInfo = proc_layout_info(RttiProcLabel,
         EntryLabel,
         Detism,
@@ -522,15 +531,23 @@
             valid_proc_layout(ProcLayoutInfo)
         ->
             construct_trace_layout(RttiProcLabel, EvalMethod, EffTraceLevel,
-                MaybeCallLabel, MaxTraceReg, HeadVars, ArgModes, Goal,
-                NeedGoalRep, InstMap, TraceSlotInfo,
-                VarSet, VarTypes, MaybeTableInfo,
-                NeedsAllNames, VarNumMap, ExecTrace, !Info),
+                MaybeCallLabel, MaxTraceReg, HeadVars, ArgModes, TraceSlotInfo,
+                VarSet, VarTypes, MaybeTableInfo, NeedsAllNames, VarNumMap,
+                InternalLabelInfos, ExecTrace, !Info),
             MaybeExecTrace = yes(ExecTrace)
         ;
             MaybeExecTrace = no
         ),
-        More = proc_id(MaybeProcStatic, MaybeExecTrace)
+        (
+            NeedGoalRep = no,
+            ProcBytes = []
+        ;
+            NeedGoalRep = yes,
+            ModuleInfo = !.Info ^ module_info,
+            represent_proc_as_bytecodes(HeadVars, Goal, InstMap, VarTypes,
+                VarNumMap, ModuleInfo, !Info, ProcBytes)
+        ),
+        More = proc_id(MaybeProcStatic, MaybeExecTrace, ProcBytes)
     ),
     ProcLayout = proc_layout_data(RttiProcLabel, Traversal, More),
     LayoutName = proc_layout(RttiProcLabel, Kind),
@@ -548,30 +565,27 @@
 
 :- pred construct_trace_layout(rtti_proc_label::in,
     eval_method::in, trace_level::in, maybe(label)::in, int::in,
-    list(prog_var)::in, list(mer_mode)::in, hlds_goal::in, bool::in,
-    instmap::in, trace_slot_info::in, prog_varset::in, vartypes::in,
+    list(prog_var)::in, list(mer_mode)::in,
+    trace_slot_info::in, prog_varset::in, vartypes::in,
     maybe(proc_table_info)::in, bool::in, var_num_map::in,
-    proc_layout_exec_trace::out,
+    list(internal_label_info)::in, proc_layout_exec_trace::out,
     stack_layout_info::in, stack_layout_info::out) is det.
 
 construct_trace_layout(RttiProcLabel, EvalMethod, EffTraceLevel,
-        MaybeCallLabel, MaxTraceReg, HeadVars, ArgModes,
-        Goal, NeedGoalRep, InstMap, TraceSlotInfo, _VarSet, VarTypes,
-        MaybeTableInfo, NeedsAllNames, VarNumMap, ExecTrace, !Info) :-
+        MaybeCallLabel, MaxTraceReg, HeadVars, ArgModes, TraceSlotInfo,
+        _VarSet, VarTypes, MaybeTableInfo, NeedsAllNames, VarNumMap,
+        InternalLabelInfos, ExecTrace, !Info) :-
+    collect_event_data_addrs(InternalLabelInfos,
+        [], RevInterfaceEventDataAddrs, [], RevInternalEventDataAddrs),
+    list.reverse(RevInterfaceEventDataAddrs, InterfaceEventDataAddrs),
+    list.reverse(RevInternalEventDataAddrs, InternalEventDataAddrs),
+    EventDataAddrs = InterfaceEventDataAddrs ++ InternalEventDataAddrs,
     construct_var_name_vector(VarNumMap,
         NeedsAllNames, MaxVarNum, VarNameVector, !Info),
     list.map(convert_var_to_int(VarNumMap), HeadVars, HeadVarNumVector),
-    ModuleInfo = !.Info ^ module_info,
-    (
-        NeedGoalRep = no,
-        ProcBytes = []
-    ;
-        NeedGoalRep = yes,
-        prog_rep.represent_proc(HeadVars, Goal, InstMap, VarTypes, VarNumMap,
-            ModuleInfo, !Info, ProcBytes)
-    ),
     TraceSlotInfo = trace_slot_info(MaybeFromFullSlot, MaybeIoSeqSlot,
         MaybeTrailSlots, MaybeMaxfrSlot, MaybeCallTableSlot),
+    ModuleInfo = !.Info ^ module_info,
     (
         MaybeCallLabel = yes(CallLabel),
         % The label associated with an event must have variable info.
@@ -607,12 +621,58 @@
     ),
     encode_exec_trace_flags(ModuleInfo, HeadVars, ArgModes, VarTypes,
         0, Flags),
-    ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails, ProcBytes,
-        MaybeTableDataAddr, HeadVarNumVector, VarNameVector,
+    ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails,
+        EventDataAddrs, MaybeTableDataAddr, HeadVarNumVector, VarNameVector,
         MaxVarNum, MaxTraceReg, MaybeFromFullSlot, MaybeIoSeqSlot,
         MaybeTrailSlots, MaybeMaxfrSlot, EvalMethod,
         MaybeCallTableSlot, EffTraceLevel, Flags).
 
+:- pred collect_event_data_addrs(list(internal_label_info)::in,
+    list(data_addr)::in, list(data_addr)::out,
+    list(data_addr)::in, list(data_addr)::out) is det.
+
+collect_event_data_addrs([], !RevInterfaces, !RevInternals).
+collect_event_data_addrs([Info | Infos], !RevInterfaces, !RevInternals) :-
+    Info = internal_label_info(ProcLabel, LabelNum, LabelVars, InternalInfo),
+    InternalInfo = internal_layout_info(MaybePortInfo, _, _),
+    (
+        MaybePortInfo = no
+    ;
+        MaybePortInfo = yes(PortInfo),
+        Port = PortInfo ^ port_type,
+        (
+            ( Port = port_call
+            ; Port = port_exit
+            ; Port = port_redo
+            ; Port = port_fail
+            ),
+            LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
+            DataAddr = layout_addr(LayoutName),
+            !:RevInterfaces = [DataAddr | !.RevInterfaces]
+        ;
+            ( Port = port_ite_cond
+            ; Port = port_ite_then
+            ; Port = port_ite_else
+            ; Port = port_neg_enter
+            ; Port = port_neg_success
+            ; Port = port_neg_failure
+            ; Port = port_disj_first
+            ; Port = port_disj_later
+            ; Port = port_switch
+            ; Port = port_nondet_foreign_proc_first
+            ; Port = port_nondet_foreign_proc_later
+            ; Port = port_user
+            ),
+            LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
+            DataAddr = layout_addr(LayoutName),
+            !:RevInternals = [DataAddr | !.RevInternals]
+        ;
+            Port = port_exception
+            % This port is attached to call sites, so there is no event here.
+        )
+    ),
+    collect_event_data_addrs(Infos, !RevInterfaces, !RevInternals).
+
 :- pred encode_exec_trace_flags(module_info::in, list(prog_var)::in,
     list(mer_mode)::in, vartypes::in, int::in, int::out) is det.
 
@@ -787,7 +847,7 @@
     %
 :- pred construct_internal_layout(proc_label::in,
     layout_name::in, var_num_map::in, pair(int, internal_layout_info)::in,
-    {proc_label, int, label_vars, internal_layout_info}::out,
+    internal_label_info::out,
     stack_layout_info::in, stack_layout_info::out) is det.
 
 construct_internal_layout(ProcLabel, ProcLayoutName, VarNumMap,
@@ -940,7 +1000,8 @@
     LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
     Label = internal_label(LabelNum, ProcLabel),
     add_internal_layout_data(LayoutData, Label, LayoutName, !Info),
-    LabelLayout = {ProcLabel, LabelNum, LabelVars, Internal}.
+    LabelLayout = internal_label_info(ProcLabel, LabelNum, LabelVars,
+        Internal).
 
 :- pred construct_user_data_array(var_num_map::in,
     list(maybe(user_attribute))::in,
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.523
diff -u -r1.523 user_guide.texi
--- doc/user_guide.texi	7 Jun 2007 06:53:52 -0000	1.523
+++ doc/user_guide.texi	9 Jun 2007 01:10:07 -0000
@@ -3309,6 +3309,52 @@
 its invocation condition is @samp{interface},
 the ignore count is zero, and the print list is empty.
 @sp 1
+ at item break [-OPS] [-E at var{ignore-count}] [-I at var{ignore-count}] [-n] [-p at var{print-spec}]* @var{proc-spec} @var{portname}
+Puts a break point on
+one or more events of the specified type in the specified procedure.
+Port names should be specified as they are printed at events,
+e.g. @samp{CALL}, @samp{EXIT}, @samp{DISJ}, @samp{SWTC}, etc.
+ at sp 1
+The option @samp{-O} or @samp{--select-one}
+selects the action to be taken
+if the specification matches more than one procedure.
+If you have specified option @samp{-O} or @samp{--select-one},
+mdb will report an error;
+otherwise, mdb will ask you which of the matched procedures you want to select.
+ at sp 1
+If there is only one event of the given type in the specified procedure,
+mdb will put the breakpoint on it;
+otherwise, it will ask you whether you want to put a breakpoint
+on all matched events or just one, and if so, which one.
+ at sp 1
+The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
+specify the action to be taken at the break point.
+ at sp 1
+The options @samp{-E at var{ignore-count}}
+and @samp{--ignore-entry @var{ignore-count}}
+tell the debugger to ignore the breakpoint
+until after @var{ignore-count} occurrences of a call event
+that matches the breakpoint.
+The options @samp{-I at var{ignore-count}}
+and @samp{--ignore-interface @var{ignore-count}}
+tell the debugger to ignore the breakpoint
+until after @var{ignore-count} occurrences of interface events
+that match the breakpoint.
+ at sp 1
+Each occurrence of the options
+ at samp{-p at var{printspec}} and @samp{--print-list @var{printspec}}
+tells the debugger to include the specified entity
+in the breakpoint's print list.
+ at sp 1
+Normally, if a variable with the given name or number doesn't exist
+when execution reaches the breakpoint, mdb will issue a warning.
+The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
+This can be useful if e.g. the name is the name of an output variable,
+which of course won't be present at call events.
+ at sp 1
+By default, the action of the break point is @samp{stop},
+the ignore count is zero, and the print list is empty.
+ at sp 1
 @item break [-PS] [-E at var{ignore-count}] [-I at var{ignore-count}] [-n] [-p at var{print-spec}]* here
 Puts a break point on the procedure referred to by the current event,
 with the invocation condition being the event at the current location
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.49
diff -u -r1.49 mercury_goto.h
--- runtime/mercury_goto.h	3 Jan 2007 05:17:16 -0000	1.49
+++ runtime/mercury_goto.h	6 Jun 2007 08:57:35 -0000
@@ -158,6 +158,72 @@
 	MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8)),		\
 	MR_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln9)),
 
+#define MR_DECL_LABEL_LAYOUT(label)					\
+	static const MR_LabelLayout MR_LABEL_LAYOUT_NAME(label);
+
+#define MR_DECL_LABEL_LAYOUT1(e, ln1)					\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1))
+
+#define MR_DECL_LABEL_LAYOUT2(e, ln1, ln2)				\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2))
+
+#define MR_DECL_LABEL_LAYOUT3(e, ln1, ln2, ln3)				\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3))
+
+#define MR_DECL_LABEL_LAYOUT4(e, ln1, ln2, ln3, ln4)			\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4))
+
+#define MR_DECL_LABEL_LAYOUT5(e, ln1, ln2, ln3, ln4, ln5)		\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5))
+
+#define MR_DECL_LABEL_LAYOUT6(e, ln1, ln2, ln3, ln4, ln5, ln6)		\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6))
+
+#define MR_DECL_LABEL_LAYOUT7(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7)	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7))
+
+#define MR_DECL_LABEL_LAYOUT8(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8) \
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8))
+
+#define MR_DECL_LABEL_LAYOUT9(e, ln1, ln2, ln3, ln4, ln5, ln6, ln7, ln8, ln9) \
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln1)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln2)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln3)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln4)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln5)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln6)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln7)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln8)) 	\
+	MR_DECL_LABEL_LAYOUT(MR_label_name(MR_add_prefix(e), ln9))
+
 /*
 ** Passing the name of a label to MR_insert_{internal,entry}_label
 ** causes that name to be included in the executable as static readonly data.
@@ -473,17 +539,17 @@
   #endif
 
 #elif defined(__arm__)
-	
+
    /*
    ** The following code for supporting non-local gotos and PIC on ARM
    ** is thanks to Sergey Khorev <iamphet at nm.ru>.
    */
    #if MR_PIC
- 
+
      /*
      ** At each entry point, where we may have been jumped to from
      ** code in a different C file, we need to set up the PIC register.
-     ** We do this by adding _GLOBAL_OFFSET_TABLE_ value to the PC register 
+     ** We do this by adding _GLOBAL_OFFSET_TABLE_ value to the PC register
      ** Current instruction address is (PC - 8) hence -(0b + 8)
      ** (I don't understand the details exactly, this code is
      ** basically copied from the output of `gcc -fpic -S' for a function
@@ -497,13 +563,13 @@
      ** can safely keep GCC uninformed because we just do GCC's work
      ** and the PIC register is saved over call
      ** Loading arbitrary immediate values into ARM registers is not possible
-     ** directly hence the .word directive in the code section and the branch 
+     ** directly hence the .word directive in the code section and the branch
      ** instruction bypassing it.
      ** If you change MR_ARM_PIC_REG, update CFLAGS_FOR_PIC (-mpic-register)
      ** in configure.in.
      */
      #define MR_ARM_PIC_REG "sl"
- 
+
      #define MR_INLINE_ASM_FIXUP_REGS				\
        "	    ldr	" MR_ARM_PIC_REG ", 1f\n"			\
        "0:\n"							\
@@ -512,7 +578,7 @@
        "1:\n"							\
        "	    .word	_GLOBAL_OFFSET_TABLE_-(0b+8)\n"		\
        "2:\n"
- 
+
      /*
      ** For Linux-ELF shared libraries, we need to declare that the type of
      ** labels is #function (i.e. code, not data), otherwise the dynamic
@@ -523,13 +589,13 @@
        #define MR_INLINE_ASM_ENTRY_LABEL_TYPE(label) \
  	  "	.type _entry_" MR_STRINGIFY(label) ",#function\n"
      #endif
- 
+
      /*
      ** Save a few clock ticks branching past MR_INLINE_ASM_FIXUP_REGS
      */
      #define MR_ASM_FALLTHROUGH(label) \
        goto MR_skip(label);
- 
+
    #endif
 
 #endif
@@ -703,7 +769,7 @@
   					general-purpose register
   	)
   */
-	
+
   /*
   ** The following macro expands into a dummy assembler statement that
   ** contains no code.  It is used to suppress optimizations in gcc 4
@@ -723,11 +789,11 @@
 		:			No inputs.
 		:"memory"		Tells gcc that this "instruction" might
 					clobber the register contents so it
-					shouldn't cache memory values in 
+					shouldn't cache memory values in
 					registers.
 	)
    */
-  
+
   /*
   ** Since we're jumping into and out of the middle of functions,
   ** we need to make sure that gcc thinks that (1) the function's address
@@ -1210,7 +1276,7 @@
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));
 
-#define	MR_init_label_sl4(e, ln1, ln2, ln3, ln4)				\
+#define	MR_init_label_sl4(e, ln1, ln2, ln3, ln4)			\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
@@ -1223,7 +1289,7 @@
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln4));		\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln5));
 
-#define	MR_init_label_sl6(e, ln1, ln2, ln3, ln4, ln5, ln6)			\
+#define	MR_init_label_sl6(e, ln1, ln2, ln3, ln4, ln5, ln6)		\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln1));		\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln2));		\
 	MR_init_label_sl(MR_label_name(MR_add_prefix(e), ln3));		\
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.111
diff -u -r1.111 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	28 May 2007 06:32:41 -0000	1.111
+++ runtime/mercury_stack_layout.h	12 Jun 2007 01:05:42 -0000
@@ -846,10 +846,12 @@
 ** containing the procedure. This allows the debugger access to the string table
 ** stored there, as well the table associating source-file contexts with labels.
 **
-** The body_bytes field contains a pointer to an array of bytecodes that
-** represents the body of the procedure. It will be a null pointer if no
-** representation is available. If it is not null pointer, then it should
-** be interpreted by read_proc_rep in browser/declarative_execution.m.
+** The labels field contains a pointer to an array of pointers to label layout
+** structures; the size of the array is given by the num_labels field. The
+** initial part of the array will contain a pointer to the label layout
+** structure of every interface event in the procedure; the later parts will
+** contain a pointer to the label layout structure of every internal event.
+** There is no ordering on the events beyond interface first, internal second.
 **
 ** The used_var_names field points to an array that contains offsets
 ** into the string table, with the offset at index i-1 giving the name of
@@ -950,8 +952,8 @@
 typedef	struct MR_ExecTrace_Struct {
 	const MR_LabelLayout	*MR_exec_call_label;
 	const MR_ModuleLayout	*MR_exec_module_layout;
-	const MR_uint_least8_t	*MR_exec_body_bytes;
-	MR_Word			MR_exec_unused;
+	const MR_LabelLayout	**MR_exec_labels;
+	MR_uint_least32_t	MR_exec_num_labels;
 	MR_TableInfo		MR_exec_table_info;
 	const MR_uint_least16_t	*MR_exec_head_var_nums;
 	const MR_uint_least32_t	*MR_exec_used_var_names;
@@ -1003,6 +1005,13 @@
 **   MR_ProcStatic structure will be generated only if the module is compiled
 **   in a deep profiling grade.
 **
+**   The body_bytes field also belongs to this group. If this is NULL, 
+**   it means that no representation of the procedure body is available.
+**   If non-NULL, it contains a pointer to an array of bytecodes that
+**   represents the body of the procedure. The bytecode array should be
+**   interpreted by read_proc_rep in browser/declarative_execution.m
+**   (it starts with an encoded form of the array's length).
+**
 ** The runtime system considers all proc layout structures to be of type
 ** MR_ProcLayout, but must use the macros defined below to check for the
 ** existence of each substructure before accessing the fields of that
@@ -1015,7 +1024,9 @@
 ** If the options with which a module is compiled do not require execution
 ** tracing, then the MR_ExecTrace substructure will not present, and if the
 ** options do not require procedure identification, then the MR_ProcId
-** substructure will not be present either
+** substructure will not be present either. The body_bytes field cannot be
+** non-NULL unless at least one of exec trace and proc static substructures
+** is present, but it is otherwise independent of those substructures.
 **
 ** The compiler itself generates proc layout structures using the following
 ** three types.
@@ -1033,6 +1044,7 @@
 	MR_ProcId				MR_sle_proc_id;
 	MR_STATIC_CODE_CONST MR_ExecTrace	*MR_sle_exec_trace;
 	MR_ProcStatic				*MR_sle_proc_static;
+	const MR_uint_least8_t			*MR_sle_body_bytes;
 };
 
 typedef	struct MR_ProcLayoutUser_Struct {
@@ -1040,6 +1052,7 @@
 	MR_UserProcId				MR_user_id;
 	MR_STATIC_CODE_CONST MR_ExecTrace	*MR_sle_exec_trace;
 	MR_ProcStatic				*MR_sle_proc_static;
+	const MR_uint_least8_t			*MR_sle_body_bytes;
 } MR_ProcLayoutUser;
 
 typedef	struct MR_ProcLayoutUCI_Struct {
@@ -1047,6 +1060,7 @@
 	MR_UCIProcId				MR_uci_id;
 	MR_STATIC_CODE_CONST MR_ExecTrace	*MR_sle_exec_trace;
 	MR_ProcStatic				*MR_sle_proc_static;
+	const MR_uint_least8_t			*MR_sle_body_bytes;
 } MR_ProcLayoutUCI;
 
 typedef	struct MR_ProcLayout_Traversal_Struct {
@@ -1071,7 +1085,8 @@
 
 #define	MR_sle_call_label	MR_sle_exec_trace->MR_exec_call_label
 #define	MR_sle_module_layout	MR_sle_exec_trace->MR_exec_module_layout
-#define	MR_sle_body_bytes       MR_sle_exec_trace->MR_exec_body_bytes
+#define	MR_sle_labels           MR_sle_exec_trace->MR_exec_labels
+#define	MR_sle_num_labels       MR_sle_exec_trace->MR_exec_num_labels
 #define	MR_sle_tabling_pointer	MR_sle_exec_trace->MR_exec_tabling_pointer
 #define	MR_sle_table_info	MR_sle_exec_trace->MR_exec_table_info
 #define	MR_sle_head_var_nums	MR_sle_exec_trace->MR_exec_head_var_nums
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/breakpoints.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp,v
retrieving revision 1.17
diff -u -r1.17 breakpoints.exp
--- tests/debugger/breakpoints.exp	19 Jan 2007 04:42:47 -0000	1.17
+++ tests/debugger/breakpoints.exp	8 Jun 2007 08:43:00 -0000
@@ -32,9 +32,9 @@
 mdb> break safe
  2: + stop  interface pred breakpoints.safe/1-0 (semidet)
 mdb> break -e qperm
- 3: + stop      entry pred breakpoints.qperm/2-0 (nondet)
+ 3: + stop  entry     pred breakpoints.qperm/2-0 (nondet)
 mdb> break -a qperm
- 4: + stop        all pred breakpoints.qperm/2-0 (nondet)
+ 4: + stop  all       pred breakpoints.qperm/2-0 (nondet)
 mdb> break /
 Ambiguous procedure specification. The matches are:
 0: func breakpoints.//2-0 (det)
@@ -63,8 +63,8 @@
  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)
+ 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)
@@ -77,8 +77,8 @@
 mdb> break info
  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)
+ 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)
@@ -87,7 +87,7 @@
 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)
+ 3: - stop  entry     pred breakpoints.qperm/2-0 (nondet)
 mdb> break nodiag
  0: + stop  interface pred breakpoints.nodiag/3-0 (semidet)
 mdb> break_print -v -n -b1 HeadVar__1 HeadVar__2
@@ -145,8 +145,8 @@
  0: E stop  interface pred breakpoints.nodiag/3-0 (semidet)
  1: E stop  interface pred breakpoints.qperm/2-0 (nondet)
  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)
+ 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)
Index: tests/debugger/breakpoints.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp2,v
retrieving revision 1.13
diff -u -r1.13 breakpoints.exp2
--- tests/debugger/breakpoints.exp2	19 Jan 2007 04:42:47 -0000	1.13
+++ tests/debugger/breakpoints.exp2	8 Jun 2007 18:08:44 -0000
@@ -32,9 +32,9 @@
 mdb> break safe
  2: + stop  interface pred breakpoints.safe/1-0 (semidet)
 mdb> break -e qperm
- 3: + stop      entry pred breakpoints.qperm/2-0 (nondet)
+ 3: + stop  entry     pred breakpoints.qperm/2-0 (nondet)
 mdb> break -a qperm
- 4: + stop        all pred breakpoints.qperm/2-0 (nondet)
+ 4: + stop  all       pred breakpoints.qperm/2-0 (nondet)
 mdb> break /
 Ambiguous procedure specification. The matches are:
 0: func breakpoints.//2-0 (det)
@@ -71,8 +71,8 @@
  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)
+ 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)
@@ -85,8 +85,8 @@
 mdb> break info
  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)
+ 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)
@@ -95,7 +95,7 @@
 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)
+ 3: - stop  entry     pred breakpoints.qperm/2-0 (nondet)
 mdb> break nodiag
  0: + stop  interface pred breakpoints.nodiag/3-0 (semidet)
 mdb> break_print -v -n -b1 HeadVar__1 HeadVar__2
@@ -153,8 +153,8 @@
  0: E stop  interface pred breakpoints.nodiag/3-0 (semidet)
  1: E stop  interface pred breakpoints.qperm/2-0 (nondet)
  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)
+ 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)
Index: tests/debugger/implied_instance.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/implied_instance.exp,v
retrieving revision 1.11
diff -u -r1.11 implied_instance.exp
--- tests/debugger/implied_instance.exp	6 Jan 2007 10:56:25 -0000	1.11
+++ tests/debugger/implied_instance.exp	8 Jun 2007 05:26:52 -0000
@@ -15,7 +15,7 @@
 mdb> P
        HeadVar__1             	2
 mdb> break -e p
- 0: + stop      entry pred implied_instance.p/2-0 (det)
+ 0: + stop  entry     pred implied_instance.p/2-0 (det)
 mdb> continue -a
        4:      4  4 CALL pred implied_instance.copy_int/2-0 (det)
        5:      4  4 EXIT pred implied_instance.copy_int/2-0 (det)
Index: tests/debugger/lval_desc_array.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/lval_desc_array.exp,v
retrieving revision 1.4
diff -u -r1.4 lval_desc_array.exp
--- tests/debugger/lval_desc_array.exp	30 Jan 2003 05:59:26 -0000	1.4
+++ tests/debugger/lval_desc_array.exp	8 Jun 2007 05:27:14 -0000
@@ -5,7 +5,7 @@
 Contexts will not be printed.
 mdb> register --quiet
 mdb> break -E 107 -e lval_desc_array__increment
- 0: + stop      entry pred lval_desc_array.increment/2-0 (det)
+ 0: + stop  entry     pred lval_desc_array.increment/2-0 (det)
             (ignore next 107 call events)
 mdb> continue
      217:    110  3 CALL pred lval_desc_array.increment/2-0 (det)
Index: tests/debugger/lval_desc_array.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/lval_desc_array.exp2,v
retrieving revision 1.3
diff -u -r1.3 lval_desc_array.exp2
--- tests/debugger/lval_desc_array.exp2	30 Jan 2003 05:59:26 -0000	1.3
+++ tests/debugger/lval_desc_array.exp2	8 Jun 2007 18:11:03 -0000
@@ -5,7 +5,7 @@
 Contexts will not be printed.
 mdb> register --quiet
 mdb> break -E 107 -e lval_desc_array__increment
- 0: + stop      entry pred lval_desc_array.increment/2-0 (det)
+ 0: + stop  entry     pred lval_desc_array.increment/2-0 (det)
             (ignore next 107 call events)
 mdb> continue
      431:    217  3 CALL pred lval_desc_array.increment/2-0 (det)
Index: tests/debugger/queens.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/queens.exp,v
retrieving revision 1.35
diff -u -r1.35 queens.exp
--- tests/debugger/queens.exp	26 Apr 2007 09:10:47 -0000	1.35
+++ tests/debugger/queens.exp	8 Jun 2007 09:06:30 -0000
@@ -360,8 +360,10 @@
  0: E stop  interface pred queens.print_list/3-0 (det)
  1: D stop  interface pred queens.qdelete/3-0 (nondet)
  2: E stop  linenumber queens.m:40
-mdb> break main
- 0: + stop  interface pred queens.main/2-0 (cc_multi)
+mdb> break main SWTC
+There is no SWTC port in pred queens.main/2-0 (cc_multi).
+mdb> break main EXIT
+ 0: + stop  specific  pred queens.main/2-0 (cc_multi) EXIT 
 mdb> continue -n
 [1, 3, 5, 2, 4]
      E60:     C1 EXIT queens.m:14
@@ -371,16 +373,21 @@
 Are you sure you want to do it? yes
       E1:     C1 CALL queens.m:14
                          pred queens.main/2-0 (cc_multi)
-mdb> break nodiag
- 1: + stop  interface pred queens.nodiag/3-0 (semidet)
+mdb> break nodiag SWTC
+Ambiguous port specification. The matches are:
+0: SWTC s1-2;
+1: SWTC s2-2;
+
+Which do you want to put a breakpoint on (0-1 or *)? 1
+ 1: + stop  specific  pred queens.nodiag/3-0 (semidet) SWTC s2-2;
 mdb> continue
-     E40:    C16 CALL queens.m:60 (from queens.m:54)
-                         pred queens.nodiag/3-0 (semidet)
+     E41:    C16 SWTC queens.m:61
+                         pred queens.nodiag/3-0 (semidet) s2-2;
 mdb> print *
        B (arg 1)              	1
        D (arg 2)              	1
        HeadVar__3             	[2, 3, 4, 5]
 mdb> delete 0
- 0: E stop  interface pred queens.main/2-0 (cc_multi)
+ 0: E stop  specific  pred queens.main/2-0 (cc_multi) EXIT 
 mdb> continue -n -S
 [1, 3, 5, 2, 4]
Index: tests/debugger/queens.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/queens.exp2,v
retrieving revision 1.16
diff -u -r1.16 queens.exp2
--- tests/debugger/queens.exp2	26 Apr 2007 09:10:47 -0000	1.16
+++ tests/debugger/queens.exp2	8 Jun 2007 18:15:01 -0000
@@ -368,8 +368,10 @@
  0: E stop  interface pred queens.print_list/3-0 (det)
  1: D stop  interface pred queens.qdelete/3-0 (nondet)
  2: E stop  linenumber queens.m:40
-mdb> break main
- 0: + stop  interface pred queens.main/2-0 (cc_multi)
+mdb> break main SWTC
+There is no SWTC port in pred queens.main/2-0 (cc_multi).
+mdb> break main EXIT
+ 0: + stop  specific  pred queens.main/2-0 (cc_multi) EXIT 
 mdb> continue -n
 [1, 3, 5, 2, 4]
      E64:     C1 EXIT queens.m:14
@@ -379,16 +381,21 @@
 Are you sure you want to do it? yes
       E1:     C1 CALL queens.m:14
                          pred queens.main/2-0 (cc_multi)
-mdb> break nodiag
- 1: + stop  interface pred queens.nodiag/3-0 (semidet)
+mdb> break nodiag SWTC
+Ambiguous port specification. The matches are:
+0: SWTC s1-2;
+1: SWTC s2-2;
+
+Which do you want to put a breakpoint on (0-1 or *)? 1
+ 1: + stop  specific  pred queens.nodiag/3-0 (semidet) SWTC s2-2;
 mdb> continue
-     E40:    C16 CALL queens.m:60 (from queens.m:54)
-                         pred queens.nodiag/3-0 (semidet)
+     E41:    C16 SWTC queens.m:61
+                         pred queens.nodiag/3-0 (semidet) s2-2;
 mdb> print *
        B (arg 1)              	1
        D (arg 2)              	1
        HeadVar__3             	[2, 3, 4, 5]
 mdb> delete 0
- 0: E stop  interface pred queens.main/2-0 (cc_multi)
+ 0: E stop  specific  pred queens.main/2-0 (cc_multi) EXIT 
 mdb> continue -n -S
 [1, 3, 5, 2, 4]
Index: tests/debugger/queens.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/queens.inp,v
retrieving revision 1.17
diff -u -r1.17 queens.inp
--- tests/debugger/queens.inp	26 Apr 2007 09:10:47 -0000	1.17
+++ tests/debugger/queens.inp	8 Jun 2007 09:03:53 -0000
@@ -97,11 +97,13 @@
 continue -n
 continue -n
 delete *
-break main
+break main SWTC
+break main EXIT
 continue -n
 retry
 yes
-break nodiag
+break nodiag SWTC
+1
 continue
 print *
 delete 0
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace_cmd_breakpoint.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_cmd_breakpoint.c,v
retrieving revision 1.3
diff -u -r1.3 mercury_trace_cmd_breakpoint.c
--- trace/mercury_trace_cmd_breakpoint.c	19 Jan 2007 04:42:50 -0000	1.3
+++ trace/mercury_trace_cmd_breakpoint.c	8 Jun 2007 04:15:31 -0000
@@ -37,6 +37,7 @@
         MR_MULTIMATCH_ASK, MR_MULTIMATCH_ALL, MR_MULTIMATCH_ONE
 } MR_MultiMatch;
 
+static  MR_bool     MR_matches_port_name(const char *word);
 static  const char  *MR_parse_spy_print(MR_BrowseFormat format, MR_bool warn,
                         char *word, MR_SpyPrint *sp_ptr);
 static  MR_SpyPrintList
@@ -103,13 +104,12 @@
         return KEEP_INTERACTING;
     }
 
+    MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+
     when = MR_default_breakpoint_scope;
     action = MR_SPY_STOP;
     multi_match = MR_MULTIMATCH_ASK;
-    /*
-    ** The value of ignore_when doesn't matter
-    ** while ignore_count contains zero.
-    */
+    /* The value of ignore_when doesn't matter while ignore_count == 0. */
     ignore_when = MR_SPY_DONT_IGNORE;
     ignore_count = 0;
     print_list = NULL;
@@ -142,8 +142,6 @@
             return KEEP_INTERACTING;
         }
 
-        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
-
         if (user_event_name != NULL) {
             found_event_set = MR_FALSE;
             found_event_name = MR_FALSE;
@@ -215,7 +213,6 @@
             return KEEP_INTERACTING;
         }
 
-        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
         slot = MR_add_user_event_spy_point(action, ignore_when, ignore_count,
             user_event_set, user_event_name, print_list, &problem);
         MR_maybe_print_spy_point(slot, problem);
@@ -236,8 +233,6 @@
             return KEEP_INTERACTING;
         }
 
-        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
-
         if (user_event_set != NULL) {
             found_event_set = MR_FALSE;
             for (set = 0; set < MR_trace_event_set_next; set++) {
@@ -268,7 +263,6 @@
             return KEEP_INTERACTING;
         }
 
-        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
         slot = MR_add_user_event_spy_point(action, ignore_when, ignore_count,
             user_event_set, NULL, print_list, &problem);
         MR_maybe_print_spy_point(slot, problem);
@@ -292,7 +286,6 @@
             return KEEP_INTERACTING;
         }
 
-        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
         slot = MR_add_proc_spy_point(MR_SPY_SPECIFIC, action, ignore_when,
             ignore_count, layout->MR_sll_entry, layout, print_list, &problem);
         MR_maybe_print_spy_point(slot, problem);
@@ -300,7 +293,6 @@
         MR_MatchesInfo  matches;
         int             slot;
 
-        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
         matches = MR_search_for_matching_procedures(&proc_spec);
         if (matches.match_proc_next == 0) {
             fflush(MR_mdb_out);
@@ -324,8 +316,7 @@
             int     i;
             char    *line2;
 
-            fflush(MR_mdb_out);
-            fprintf(MR_mdb_err,
+            fprintf(MR_mdb_out,
                 "Ambiguous procedure specification. The matches are:\n");
 
             for (i = 0; i < matches.match_proc_next; i++) {
@@ -368,6 +359,151 @@
                 MR_free(line2);
             }
         }
+    } else if (word_count == 3 && MR_parse_proc_spec(words[1], &proc_spec) &&
+        MR_matches_port_name(words[2]) && MR_strdiff(words[2], "EXCP"))
+    {
+        const MR_ProcLayout     *selected_proc;
+        const MR_LabelLayout    *selected_label;
+        MR_MatchesInfo          matches;
+        MR_TracePort            port;
+        const MR_LabelLayout    **matching_labels;
+        int                     matching_port_count;
+        int                     slot;
+        int                     i;
+
+        if (multi_match == MR_MULTIMATCH_ALL) {
+            fprintf(MR_mdb_err, "Warning: "
+                "the -A option is ignored when a port is specified.\n");
+            multi_match = MR_MULTIMATCH_ASK;
+        }
+
+        matches = MR_search_for_matching_procedures(&proc_spec);
+        if (matches.match_proc_next == 0) {
+            fflush(MR_mdb_out);
+            fprintf(MR_mdb_err, "mdb: there is no such procedure.\n");
+            return KEEP_INTERACTING;
+        } else if (matches.match_proc_next == 1) {
+            selected_proc = matches.match_procs[0];
+        } else {
+            char    buf[80];
+            char    *line2;
+
+            fprintf(MR_mdb_out,
+                "Ambiguous procedure specification. The matches are:\n");
+
+            for (i = 0; i < matches.match_proc_next; i++) {
+                fprintf(MR_mdb_out, "%d: ", i);
+                MR_print_proc_id_and_nl(MR_mdb_out, matches.match_procs[i]);
+            }
+
+            if (multi_match == MR_MULTIMATCH_ONE) {
+                return KEEP_INTERACTING;
+            }
+
+            sprintf(buf, "\nWhich do you want to put a breakpoint on (0-%d)? ",
+                matches.match_proc_next - 1);
+            line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
+            if (line2 == NULL) {
+                /* This means the user input EOF. */
+                fprintf(MR_mdb_out, "none of them\n");
+                return KEEP_INTERACTING;
+            } else if (MR_trace_is_natural_number(line2, &i)) {
+                if (0 <= i && i < matches.match_proc_next) {
+                    selected_proc = matches.match_procs[i];
+                } else {
+                    fprintf(MR_mdb_out, "no such match\n");
+                    MR_free(line2);
+                    return KEEP_INTERACTING;
+                }
+            } else {
+                fprintf(MR_mdb_out, "none of them\n");
+                MR_free(line2);
+                return KEEP_INTERACTING;
+            }
+        }
+
+        matching_port_count = 0;
+        matching_labels = MR_malloc(sizeof(const MR_LabelLayout *) *
+            selected_proc->MR_sle_num_labels);
+        for (i = 0; i < selected_proc->MR_sle_num_labels; i++) {
+            if (selected_proc->MR_sle_labels[i]->MR_sll_port < 0) {
+                continue;
+            }
+
+            port = (MR_TracePort) selected_proc->MR_sle_labels[i]->MR_sll_port;
+            if (MR_streq(MR_simplified_port_names[port], words[2])) {
+                matching_labels[matching_port_count] =
+                    selected_proc->MR_sle_labels[i];
+                matching_port_count++;
+            }
+        }
+
+        if (matching_port_count == 0) {
+            fprintf(MR_mdb_out, "There is no %s port in ", words[2]);
+            MR_print_proc_id(MR_mdb_out, selected_proc);
+            fprintf(MR_mdb_out, ".\n");
+            MR_free(matching_labels);
+            return KEEP_INTERACTING;
+        } else if (matching_port_count == 1) {
+            selected_label = matching_labels[0];
+        } else {
+            char    buf[80];
+            char    *line2;
+
+            fprintf(MR_mdb_out,
+                "Ambiguous port specification. The matches are:\n");
+
+            for (i = 0; i < matching_port_count; i++) {
+                const MR_LabelLayout    *this_label;
+
+                this_label = matching_labels[i];
+                fprintf(MR_mdb_out, "%d: %4s %s\n",
+                    i,
+                    MR_simplified_port_names[this_label->MR_sll_port],
+                    MR_label_goal_path(this_label));
+            }
+
+            sprintf(buf, "\nWhich do you want to put "
+                "a breakpoint on (0-%d or *)? ",
+                matching_port_count - 1);
+            line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
+            if (line2 == NULL) {
+                /* This means the user input EOF. */
+                fprintf(MR_mdb_out, "none of them\n");
+                MR_free(matching_labels);
+                return KEEP_INTERACTING;
+            } else if (MR_streq(line2, "*")) {
+                for (i = 0; i < matching_port_count; i++) {
+                    slot = MR_add_proc_spy_point(MR_SPY_SPECIFIC, action,
+                        ignore_when, ignore_count, selected_proc,
+                        matching_labels[i], print_list, &problem);
+                    MR_maybe_print_spy_point(slot, problem);
+                }
+
+                MR_free(matching_labels);
+                MR_free(line2);
+                return KEEP_INTERACTING;
+            } else if (MR_trace_is_natural_number(line2, &i)) {
+                if (0 <= i && i < matching_port_count) {
+                    selected_label = matching_labels[i];
+                } else {
+                    fprintf(MR_mdb_out, "no such match\n");
+                    MR_free(matching_labels);
+                    MR_free(line2);
+                    return KEEP_INTERACTING;
+                }
+            } else {
+                fprintf(MR_mdb_out, "none of them\n");
+                MR_free(matching_labels);
+                MR_free(line2);
+                return KEEP_INTERACTING;
+            }
+        }
+
+        slot = MR_add_proc_spy_point(MR_SPY_SPECIFIC, action, ignore_when,
+            ignore_count, selected_proc, selected_label, print_list, &problem);
+        MR_maybe_print_spy_point(slot, problem);
+        MR_free(matching_labels);
     } else if (word_count == 2 &&
         MR_parse_source_locn(words[1], &file, &line))
     {
@@ -854,6 +990,20 @@
 
 /****************************************************************************/
 
+static MR_bool
+MR_matches_port_name(const char *word)
+{
+    int i;
+
+    for (i = 0; i < MR_PORT_NUM_PORTS; i++) {
+        if (MR_streq(word, MR_simplified_port_names[i])) {
+            return MR_TRUE;
+        }
+    }
+
+    return MR_FALSE;
+}
+
 static const char *
 MR_parse_spy_print(MR_BrowseFormat format, MR_bool warn, char *word,
     MR_SpyPrint *sp_ptr)
Index: trace/mercury_trace_spy.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_spy.c,v
retrieving revision 1.30
diff -u -r1.30 mercury_trace_spy.c
--- trace/mercury_trace_spy.c	19 Jan 2007 04:42:51 -0000	1.30
+++ trace/mercury_trace_spy.c	8 Jun 2007 03:56:28 -0000
@@ -1081,11 +1081,12 @@
 void
 MR_print_spy_point(FILE *fp, int spy_point_num, MR_bool verbose)
 {
-    MR_SpyPoint *point;
-    MR_SpyCond  *cond;
+    MR_SpyPoint     *point;
+    MR_SpyCond      *cond;
+    MR_TracePort    port;
 
     point = MR_spy_points[spy_point_num];
-    fprintf(fp, "%2d: %1s %-5s %9s ",
+    fprintf(fp, "%2d: %1s %-5s %-9s ",
         spy_point_num,
         point->MR_spy_exists ?
             (point->MR_spy_enabled ? "+" : "-") :
@@ -1097,8 +1098,19 @@
         case MR_SPY_ALL:
         case MR_SPY_INTERFACE:
         case MR_SPY_ENTRY:
+            MR_print_proc_id(fp, point->MR_spy_proc);
+            break;
+
         case MR_SPY_SPECIFIC:
             MR_print_proc_id(fp, point->MR_spy_proc);
+            MR_assert(point->MR_spy_label != NULL);
+            port = point->MR_spy_label->MR_sll_port;
+            if (port < 0) {
+                fprintf(fp, " NONE ");
+            } else {
+                fprintf(fp, " %4s ", MR_simplified_port_names[port]);
+            }
+            fprintf(fp, "%s", MR_label_goal_path(point->MR_spy_label));
             break;
 
         case MR_SPY_LINENO:
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list