[m-dev.] for review: catch control-C in mdb

Fergus Henderson fjh at cs.mu.OZ.AU
Sat Nov 20 06:38:56 AEDT 1999


Probably Zoltan is the best person to review this one.

----------

Estimated hours taken: 2

Add support for catching interrupts (i.e. SIGINT signals,
normally generated by control-C) in the debugger.

runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
	Add declaration and definition of a new variable
	MR_address_of_trace_interrupt_handler.

runtime/mercury_trace_base.c:
	Add code to MR_trace_start() to call MR_setup_signal() to install
	the function pointed to by MR_address_of_trace_interrupt_handler
	as the signal handler for SIGINT signals.

runtime/mercury_init.h:
	Add declaration for MR_trace_interrupt_handler().

util/mkinit.c:
	Add code to initialize MR_address_of_trace_interrupt_handler
	to point to MR_trace_interrupt_handler().

trace/mercury_trace.c:
	Add MR_trace_interrupt(), which is like MR_trace_real(), except
	that it enters the interactive debugger unconditionally.
	Add MR_trace_interrupt_handler(); this function just sets
	MR_trace_func_ptr to MR_trace_interrupt(), so that a SIGINT
	will cause the interactive debugger to be entered at the
	next call to MR_trace().

trace/mercury_trace_internal.h:
trace/mercury_trace_internal.c:
	Add MR_trace_interrupt_message(), which prints a message
	indicating that the debugger caught an interrupt.

Workspace: /home/mercury0/fjh/mercury
Index: runtime/mercury_init.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_init.h,v
retrieving revision 1.16
diff -u -d -r1.16 mercury_init.h
--- mercury_init.h	1999/10/05 07:26:19	1.16
+++ mercury_init.h	1999/11/19 19:03:42
@@ -154,6 +154,9 @@
 extern	Code	*MR_trace_real(const MR_Stack_Layout_Label *, MR_Trace_Port,
 			const char *, int);
 
+/* in trace/mercury_trace.c */
+extern	void	MR_trace_interrupt_handler(void);
+
 /* in trace/mercury_trace_tables.c */
 extern	void	MR_register_module_layout_real(const MR_Module_Layout *);
 
Index: runtime/mercury_trace_base.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_base.c,v
retrieving revision 1.21
diff -u -d -r1.21 mercury_trace_base.c
--- mercury_trace_base.c	1999/11/05 02:36:23	1.21
+++ mercury_trace_base.c	1999/11/19 19:01:26
@@ -22,6 +22,8 @@
 #include "mercury_engine.h"
 #include "mercury_wrapper.h"
 #include "mercury_misc.h"
+#include "mercury_signal.h"	/* for MR_setup_signal() */
+#include <signal.h>		/* for SIGINT */
 #include <stdio.h>
 #include <unistd.h>		/* for the write system call */
 #include <errno.h>
@@ -36,7 +38,7 @@
 
 /*
 ** Compiler generated tracing code will check whether MR_trace_enabled is true,
-** before calling MR_trace. For now, and until we implement interface tracing,
+** before calling MR_trace.
 ** MR_trace_enabled should keep the same value throughout the execution of
 ** the entire program after being set in mercury_wrapper.c. There is one
 ** exception to this: the Mercury routines called as part of the functionality
@@ -205,6 +207,22 @@
 	MR_trace_call_depth = 0;
 	MR_trace_from_full = TRUE;
 	MR_trace_enabled = enabled;
+
+	/*
+	** Install the SIGINT signal handler.
+	** We only do this if tracing is enabled, and only
+	** for the internal debugger.  (This is a bit conservative:
+	** it might work fine for the external debugger too,
+	** but I'm just not certain of that.)
+	*/
+	if (enabled &&
+		MR_address_of_trace_interrupt_handler != NULL &&
+		MR_trace_handler == MR_TRACE_INTERNAL)
+	{
+		MR_setup_signal(SIGINT,
+			(Code *) MR_address_of_trace_interrupt_handler,
+			FALSE, "mdb: cannot install SIGINT signal handler");
+	}
 }
 
 void
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.49
diff -u -d -r1.49 mercury_wrapper.c
--- mercury_wrapper.c	1999/11/05 02:36:22	1.49
+++ mercury_wrapper.c	1999/11/19 18:12:02
@@ -194,6 +194,8 @@
 Code	*(*MR_trace_func_ptr)(const MR_Stack_Layout_Label *, MR_Trace_Port,
 		const char *, int);
 
+void	(*MR_address_of_trace_interrupt_handler)(void);
+
 void	(*MR_register_module_layout)(const MR_Module_Layout *);
 
 #ifdef USE_GCC_NONLOCAL_GOTOS
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.24
diff -u -d -r1.24 mercury_wrapper.h
--- mercury_wrapper.h	1999/10/10 02:35:19	1.24
+++ mercury_wrapper.h	1999/11/19 19:02:12
@@ -105,12 +105,30 @@
 ** MR_trace_func_ptr is set to either MR_trace_real (trace/mercury_trace.c), or
 ** MR_trace_fake (runtime/mercury_trace_base.c),
 ** depending on whether tracing was enabled when creating the _init.c
-** file.  It is called from MR_trace (runtime/mercury_trace_base.c).
+** file.  It is also temporarily set to MR_trace_interrupt by
+** MR_trace_interrupt_handler if tracing was enabled and the
+** process receives a SIGINT signal.
+** It is called from MR_trace (runtime/mercury_trace_base.c).
+**
+** Since it is set from a signal handler, it must be declared `volatile'.
 */
 
-extern	Code		*(*MR_trace_func_ptr)(const MR_Stack_Layout_Label *,
+extern	Code		*(*volatile MR_trace_func_ptr)(
+				const MR_Stack_Layout_Label *,
 				MR_Trace_Port, const char *, int);
 
+/*
+** If the init file was built with tracing enabled, then
+** MR_address_of_trace_interrupt_handler points to
+** MR_trace_interrupt_handler, otherwise it is NULL.
+*/
+extern	void		(*MR_address_of_trace_interrupt_handler)(void);
+
+/*
+** If the init file was built with tracing enabled, then
+** MR_register_module_layout points to MR_register_module_layout_real,
+** otherwise it is NULL.
+*/
 extern	void		(*MR_register_module_layout)(const MR_Module_Layout *);
 
 extern	void		do_init_modules(void);
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.15
diff -u -d -r1.15 mercury_trace.c
--- mercury_trace.c	1999/10/15 08:26:39	1.15
+++ mercury_trace.c	1999/11/19 19:07:47
@@ -45,6 +45,7 @@
 #include "mercury_wrapper.h"
 #include "mercury_misc.h"
 #include "mercury_array_macros.h"
+#include "mercury_init.h"
 #include <stdio.h>
 
 static	MR_Trace_Cmd_Info	MR_trace_ctrl = {
@@ -249,6 +250,60 @@
 	}
 
 	return NULL;
+}
+
+/*
+** MR_trace_interrupt() is called via a function pointer from MR_trace()
+** in runtime/mercury_trace_base.c, which in turn is called from
+** compiled code whenever an event to be traced occurs.
+** It is called whenever the user pressed control-C to interrupt the
+** program.
+** This is like MR_trace_real(), except that it _always_ calls
+** MR_trace_event().
+*/
+
+static Code *
+MR_trace_interrupt(const MR_Stack_Layout_Label *layout, MR_Trace_Port port,
+	const char *path, int max_r_num)
+{
+	Unsigned	seqno;
+	Unsigned	depth;
+
+	/* restore the original MR_trace_func_ptr value */
+	MR_trace_func_ptr = MR_trace_real;
+
+	if (MR_trace_handler == MR_TRACE_INTERNAL) {
+		MR_trace_interrupt_message();
+	}
+
+	/* in case MR_sp or MR_curfr is transient */
+	restore_transient_registers();
+
+	if (MR_DETISM_DET_STACK(layout->MR_sll_entry->MR_sle_detism)) {
+		seqno = (Unsigned) MR_call_num_stackvar(MR_sp);
+		depth = (Unsigned) MR_call_depth_stackvar(MR_sp);
+	} else {
+		seqno = (Unsigned) MR_call_num_framevar(MR_curfr);
+		depth = (Unsigned) MR_call_depth_framevar(MR_curfr);
+	}
+
+	MR_trace_event_number++;
+
+	return MR_trace_event(&MR_trace_ctrl, TRUE, layout, port, seqno, depth,
+			path, max_r_num);
+}
+
+void
+MR_trace_interrupt_handler(void)
+{
+	/*
+	** This function is a signal handler, so there is not
+	** much that we can safely do here.  We just set the volatile
+	** variable MR_trace_func_ptr; the real work will be done
+	** by MR_trace_interrupt(), which will be called by MR_trace()
+	** at the next debugger event.
+	*/ 
+	MR_trace_func_ptr = MR_trace_interrupt;
 }
 
 static Code *
Index: trace/mercury_trace_internal.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.h,v
retrieving revision 1.8
diff -u -d -u -r1.8 mercury_trace_internal.h
--- mercury_trace_internal.h	1999/05/30 03:55:13	1.8
+++ mercury_trace_internal.h	1999/11/19 18:43:11
@@ -55,6 +55,12 @@
 extern FILE *MR_mdb_out;
 extern FILE *MR_mdb_err;
 
+/*
+** This just prints to MR_mdb_out a message telling the user
+** that the debugger caught an interrupt.
+*/
+extern	void	MR_trace_interrupt_message(void);
+
 extern	char	*MR_trace_getline(const char *prompt, FILE *mdb_in,
 				FILE *mdb_out);
 
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.57
diff -u -d -r1.57 mercury_trace_internal.c
--- mercury_trace_internal.c	1999/11/15 00:43:56	1.57
+++ mercury_trace_internal.c	1999/11/19 18:46:43
@@ -2469,3 +2469,9 @@
 
 	return FALSE;
 }
+
+void
+MR_trace_interrupt_message(void)
+{
+	fprintf(MR_mdb_out, "\nmdb: got interrupt signal\n");
+}
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.56
diff -u -d -r1.56 mkinit.c
--- mkinit.c	1999/11/15 04:14:39	1.56
+++ mkinit.c	1999/11/19 18:02:58
@@ -184,9 +184,12 @@
 	"#endif\n"
 	"#if MR_TRACE_ENABLED\n"
 	"	MR_trace_func_ptr = MR_trace_real;\n"
+	"	MR_address_of_trace_interrupt_handler =\n"
+	"		MR_trace_interrupt_handler;\n"
 	"	MR_register_module_layout = MR_register_module_layout_real;\n"
 	"#else\n"
 	"	MR_trace_func_ptr = MR_trace_fake;\n"
+	"	MR_address_of_trace_interrupt_handler = NULL;"
 	"	MR_register_module_layout = NULL;\n"
 	"#endif\n"
 	"#if defined(USE_GCC_NONLOCAL_GOTOS) && !defined(USE_ASM_LABELS)\n"

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list