[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