diff: add `--trace' option for ml

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Mar 18 11:13:21 AEDT 1999


Estimated hours taken: 3

Improve the autoconfiguration for sockets and the dlopen() stuff,
and ensure that the libraries needed for these are only linked in
when debugging.

This change also fixes a bug: Erwan's recent change to add -lsocket
broke static linking on Solaris 2.6 machines.  This change means that
static linking works again, so long as you don't enable debugging.

configure.in:
	Check for `-ldl', and if present, set DL_LIBRARY.
	Change the check for the socket stuff needed for
	MR_USE_EXTERNAL_DEBUGGER to use AC_CHECK_LIB and
	AC_TRY_LINK rather than hard-coding tests against $host.

scripts/ml.in:
	Add new option `-t'/`--trace', implied by `--debug'.
	If this option is set, link against $DL_LIBRARY.  Also,
	don't link against $SOCKET_LIBRARY unless this is set.
	Document that `--static' and `--trace' are incompatible
	on some systems.

doc/user_guide.texi:
	Document the need to pass `--trace' to the linker.
	This involved rewording things a bit.

Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.152
diff -u -r1.152 configure.in
--- configure.in	1999/03/15 08:47:33	1.152
+++ configure.in	1999/03/18 00:02:55
@@ -245,6 +245,8 @@
 if test "$HAVE_DLFCN_H" = 1; then
 	AC_DEFINE(HAVE_DLFCN_H)
 fi
+AC_CHECK_LIB(dl,dlopen,DL_LIBRARY="-ldl",DL_LIBRARY="")
+AC_SUBST(DL_LIBRARY)
 AC_HAVE_FUNCS(dlopen dlclose dlsym dlerror)
 #-----------------------------------------------------------------------------#
 #
@@ -1806,40 +1808,190 @@
 
 
 #-----------------------------------------------------------------------------#
+
+#
+# check whether we need -lsocket
+#
+AC_CHECK_LIB(socket,socket,SOCKET_LIBRARY=-lsocket,SOCKET_LIBRARY="")
+AC_SUBST(SOCKET_LIBRARY)
+
+#
+# temporarily add -lsocket to LIBS, for use by AC_TRY_LINK
+#
+save_LIBS="$LIBS"
+LIBS="$LIBS $SOCKET_LIBRARY"
+
+#
+# use AC_TRY_LINK to see whether we can use sockets
+#
 AC_MSG_CHECKING(whether we can use sockets (for Opium-M))
-# test if sockets are available to be able to use Opium-M
-# XXX It would be better to use AC_TRY_RUN() to do that
+AC_CACHE_VAL(mercury_cv_sockets_work,
+AC_TRY_LINK([
+	changequote(<<,>>) 
+	/*
+	** The following code was copied from
+	** runtime/mercury_trace_external.c
+	*/
 
-SOCKET_LIBRARY= 
+	#include <stdio.h>
+	#include <string.h>
+	#include <errno.h>
+	#include <stdarg.h>
+	#include <sys/types.h>
+	#include <unistd.h>
+	#include <sys/socket.h>
+	#include <sys/un.h>
+	#include <arpa/inet.h>
+	#include <netinet/in.h>
+	#include <netdb.h>
+],[
+	static int MR_debug_socket = 1;
+
+	void
+	fatal_error(const char *s)
+	{
+		fprintf(stderr, "", s);
+		exit(1);
+	}
 
-case "$host" in
-	i?86-*-linux|i?86-*-linux-gnu)
-		AC_MSG_RESULT(yes)
-		AC_DEFINE(MR_USE_EXTERNAL_DEBUGGER)
-		;;
-	m68*-linux|m68*-linux-gnu)
-		AC_MSG_RESULT(disabled for now because it is untested)
-		;;
-	i?86-*-freebsd*)
-		AC_MSG_RESULT(disabled for now because it is untested)
-		;;
-	sparc-sun-solaris2.*)
-		AC_MSG_RESULT(yes)        
-		AC_DEFINE(MR_USE_EXTERNAL_DEBUGGER)
-		SOCKET_LIBRARY=" -lsocket"
-		;;
-	alpha-dec-osf*)
-		AC_MSG_RESULT(disabled for now because it is untested)
-		;;
-	*-cygwin*)
-		AC_MSG_RESULT(disabled for now because it is untested)
-		;;
-	*)
-		AC_MSG_RESULT(unknown system, assuming no)
-		;;
-esac
- 
-AC_SUBST(SOCKET_LIBRARY)
+	void
+	MR_trace_init_external(void)
+	{
+		int fd;
+		int len;
+		FILE *file_in;
+		FILE *file_out;
+		int addr_family;
+		char *unix_socket;
+		char *inet_socket;
+		struct sockaddr_un unix_address;
+		struct sockaddr_in inet_address;
+		struct sockaddr* addr;
+
+		/*
+		** We presume that the user's program has been invoked from
+		** within the debugger (e.g. Opium).
+		** The debugger (or the user) should set the
+		** MERCURY_DEBUGGER_UNIX_SOCKET or MERCURY_DEBUGGER_INET_SOCKET
+		** environment variable to tell the user's program which socket
+		** it needs to connect to.
+		*/
+		unix_socket = getenv("MERCURY_DEBUGGER_UNIX_SOCKET");
+		inet_socket = getenv("MERCURY_DEBUGGER_INET_SOCKET");
+		if (unix_socket == NULL && inet_socket == NULL) {
+			fatal_error("you must set either the "
+				"MERCURY_DEBUGGER_UNIX_SOCKET\n"
+				"or MERCURY_DEBUGGER_INET_SOCKET "
+				"environment variable");
+		}
+		if (unix_socket != NULL && inet_socket != NULL) {
+			fatal_error("you must set only one of the "
+				"MERCURY_DEBUGGER_UNIX_SOCKET "
+				"and MERCURY_DEBUGGER_INET_SOCKET\n"
+				"environment variables");
+		}
+		if (unix_socket) {
+		
+			addr_family = AF_UNIX;
+			memset(&unix_address, 0, sizeof(unix_address));
+			unix_address.sun_family = AF_UNIX;
+			strcpy(unix_address.sun_path, unix_socket);
+			addr = (struct sockaddr *) &unix_address;
+			len = strlen(unix_address.sun_path) + 
+				sizeof(unix_address.sun_family);
+		} else {
+			char hostname[255];
+			char port_string[255];
+			unsigned short port;
+			int host_addr;
+
+			/*
+			** Parse the MERCURY_DEBUGGER_INET_SOCKET environment variable.
+			** It should be in the format "<hostname> <port>",
+			** where <hostname> is numeric (e.g. "123.456.78.90").
+			*/
+
+			if (sscanf(inet_socket, "%254s %254s", hostname, port_string) 
+				!= 2)
+			{
+				fatal_error("MERCURY_DEBUGGER_INET_SOCKET invalid");
+			}
+			host_addr = inet_network(hostname);
+			if (host_addr == -1) {
+				fatal_error("MERCURY_DEBUGGER_INET_SOCKET: "
+					"invalid address");
+			}
+			if (sscanf(port_string, "%hu", &port) != 1) {
+				fatal_error("MERCURY_DEBUGGER_INET_SOCKET: "
+					"invalid port");
+			}
+
+			fprintf(stderr, "Mercury runtime: host = %s, port = %d\n",
+					hostname, port);
+		
+			inet_address.sin_family = AF_INET;
+			inet_address.sin_addr.s_addr = host_addr;
+			inet_address.sin_port = htons(port);
+			addr_family = AF_INET;
+			addr = (struct sockaddr *) &inet_address;
+			len = sizeof(inet_address);
+		}
+
+		/*
+		** Open the socket.
+		*/
+
+		fd = socket(addr_family, SOCK_STREAM, 0);
+		if (fd < 0) {
+			fprintf(stderr, "Mercury runtime: socket() failed: %s\n",
+				strerror(errno));
+			fatal_error("cannot open socket for debugger");
+		} else if (MR_debug_socket) {
+			fprintf(stderr,"Mercury runtime: creation of socket ok\n");
+		}
+
+		/*
+		** Connect to the socket
+		*/
+		if (connect(fd, addr, len) < 0) {
+			fprintf(stderr, "Mercury runtime: connect() failed: %s\n",
+				strerror(errno));
+			fatal_error("can't connect to debugger socket");
+		} else if (MR_debug_socket) {
+			fprintf(stderr, "Mercury runtime: connection to socket: ok\n");
+		}
+
+		/*
+		** Convert the socket fd to a Mercury stream
+		*/
+		file_in = fdopen(fd, "r");
+		file_out = fdopen(fd, "w");
+		if ((file_in == NULL)||(file_out == NULL)) {
+			fprintf(stderr, "Mercury runtime: fdopen() failed: %s\n",
+				strerror(errno));
+			fatal_error("cannot open debugger socket");
+		} else if (MR_debug_socket) {
+			fprintf(stderr, "Mercury runtime: fdopen(): ok\n");
+		}
+	}
+	changequote([,]) 
+],[mercury_cv_sockets_work=yes],[mercury_cv_sockets_work=no]))
+
+#
+# figure out whether the test succeeded, and if so,
+# enable the external debugger
+#
+if test "$mercury_cv_sockets_work" = yes; then
+	AC_MSG_RESULT(yes)
+	AC_DEFINE(MR_USE_EXTERNAL_DEBUGGER)
+else
+	AC_MSG_RESULT(no)
+fi
+
+#
+# restore the previous value of LIBS
+#
+LIBS="$save_LIBS"
 
 #-----------------------------------------------------------------------------#
 AC_OUTPUT(Mmake.common scripts/Mmake.vars scripts/mmc scripts/mprof
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.159
diff -u -r1.159 user_guide.texi
--- user_guide.texi	1999/03/15 08:47:56	1.159
+++ user_guide.texi	1999/03/17 23:37:07
@@ -1034,17 +1034,26 @@
 The table also shows that in a debugging grade,
 no module can be compiled with trace level @samp{none}.
 
-A small but vital part of preparing an executable for debugging
-is the setup of the initialization file for debugging.
-The initialization file is created by the c2init command,
-which can be told to set up the initialization file for debugging
-in one of two ways.
-First, c2init accepts the same set of grade options the compiler accepts.
-If these options specify a debugging grade,
-c2init will set up the initialization file for debugging.
-Even if these options specify a non-debugging grade,
-you can ask c2init to set up the initialization file for debugging
-by giving it the @samp{-t} (for @emph{trace}) option.
+ at strong{Important note}:
+If you are not using a debugging grade, but you compile
+some modules with @samp{--trace shallow} or @samp{--trace deep},
+then you must also pass the @samp{--trace} (or @samp{-t}) option
+to c2init and to the Mercury linker.
+If you're using Mmake, then you can do this by including @samp{--trace}
+in the @samp{C2INITFLAGS} and @samp{MLFLAGS} variables.
+
+If you're using Mmake, then you can also set the compilation options
+for a single module named @var{Module} by setting the Mmake variable
+ at samp{MCFLAGS- at var{Module}}.  For example, to compile the file
+ at file{foo.m} with deep tracing, @file{bar.m} with shallow tracing,
+and everything else with no tracing, you could use the following:
+
+ at example
+C2INITFLAGS = --trace
+MLFLAGS     = --trace
+MCFLAGS-foo = --trace deep
+MCFLAGS-bar = --trace shalow
+ at end example
 
 @node Selecting trace events
 @section Selecting trace events
Index: scripts/ml.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/ml.in,v
retrieving revision 1.52
diff -u -r1.52 ml.in
--- ml.in	1999/03/11 19:18:06	1.52
+++ ml.in	1999/03/18 00:02:14
@@ -20,8 +20,15 @@
 Options:
 	-h, --help
 		Print this help message.
+
+Diagnostics options:
 	-v, --verbose
 		Echo the gcc command line before executing it.
+	--no-demangle
+		Don't pipe the output of the linker through the Mercury
+		demangler.
+
+Dynamic/static linking options:
 	--mercury-libs {shared, static, none}
 		Specify which version of the standard Mercury libraries to
 		link with:
@@ -40,17 +47,28 @@
 		libraries, not just the standard Mercury libraries.
 	--make-shared-lib
 		Produce a shared library, rather than an executable.
+
+Directory options:
 	-L <directory>, --lib-dir <directory>
 		Include <directory> in the list of directories that the
 		linker will use to search for libraries.
 	-R <directory>, --shared-lib-dir <directory>
 		Include <directory> in the list of directories that the
 		dynamic linker will use to search for shared libraries.
-	--no-demangle
-		Don't pipe the output of the linker through the Mercury
-		demangler.
-	-g, --no-strip, --c-debug
-		Do not strip debugging information.
+
+Debugging options:
+	-t, --trace
+		Link in the Mercury debugging libraries.
+		This option is needed if any of the modules being linked
+		were compiled with tracing enabled.  However, \`--debug'
+		implies \`--trace', so if you're using \`--debug',
+		then you don't need to explicilty specify \`--trace'.
+		Note that \`--trace' is incompatible with \`--static'
+		on some platforms (e.g. sparc-sun-solaris2.6).
+	-g, --c-debug, --no-strip
+		Do not strip C debugging information.
+
+Grade options:
 	-s <grade>, --grade <grade>
 	--asm-labels
 	--gcc-non-local-gotos
@@ -88,7 +106,10 @@
 # On some systems (Solaris for exemple), we need libraries to be able to 
 # use sockets. The name of the needed libraries is determined by autoconf
 # and passed through this variable.
-SOCKET_LIBRARY=" @SOCKET_LIBRARY@"
+SOCKET_LIBRARY="@SOCKET_LIBRARY@"
+
+# Likewise for -ldl (libdl.so), which is often needed for dlopen() etc.
+DL_LIBRARY="@DL_LIBRARY@"
 
 # If you change these, you will also need to change Mmake.common.in,
 # scripts/c2init.in, tools/bootcheck, tools/binary, tools/binary_step
@@ -99,6 +120,7 @@
 BROWSER_LIB_NAME=mer_browser
 
 verbose=false
+trace=false
 case $FULLARCH in
 	*-win95|*-winnt|*-win32|*-cygwin32|*-cygwin)
 		# `gcc -s' is broken in gnu-win32
@@ -133,6 +155,12 @@
 	--no-demangle)
 		demangle=false
 		;;
+	-t|--trace)
+		trace=true
+		;;
+	-t-|--no-trace)
+		trace=false
+		;;
 	-g-|--no-c-debug|--strip)
 		strip=true
 		;;
@@ -215,6 +243,12 @@
 # include the file `final_grade_options.sh-subr'
 @FINAL_GRADE_OPTIONS@
 
+# --require-tracing (which is implied by --debug) implies --trace
+case $require_tracing in
+	true)	trace=true ;;
+	false)	;;
+esac
+
 # If you haven't set mercury_libs, set it to the default value
 # (shared on most systems). Note that if you have set all_libs,
 # it will also have set mercury_libs.
@@ -331,6 +365,19 @@
 		;;
 esac
 
+case $trace in
+	true)	TRACE_LIBS="-l$TRACE_LIB_NAME -l$BROWSER_LIB_NAME \
+			$SOCKET_LIBRARY $DL_LIB"
+		TRACE_STATIC_LIBS="\
+			$LIBDIR/$GRADE/$FULLARCH/lib$TRACE_LIB_NAME.a \
+			$LIBDIR/$GRADE/$FULLARCH/lib$BROWSER_LIB_NAME.a \
+			$SOCKET_LIBRARY $DL_LIB"
+		;;
+	false)	TRACE_LIBS=
+		TRACE_STATIC_LIBS=
+		;;
+esac
+		
 case $strip in
 	true)	STRIP_OPTS="-s" ;;
 	false)  STRIP_OPTS="" ;;
@@ -344,8 +391,8 @@
 		*-solaris*)	THREAD_LIBS="-lpthread -ldl" ;;
 		*)		echo "$0: warning: don't know which" \
 					"library to use for pthreads" 1>&2
-				 THREAD_LIBS=""
-				 ;;
+				THREAD_LIBS=""
+				;;
 		esac ;;
 	false)	THREAD_LIBS="" ;;
 esac
@@ -373,14 +420,12 @@
 
 case $mercury_libs in
 	shared)
-		LIBS=${MERCURY_LIBS="-l$TRACE_LIB_NAME -l$BROWSER_LIB_NAME -l$STD_LIB_NAME -l$RT_LIB_NAME $LIBGC $STDLIBS"}
+		LIBS=${MERCURY_LIBS="$TRACE_LIBS -l$STD_LIB_NAME -l$RT_LIB_NAME $LIBGC $STDLIBS"}
 		merc_shlib_dirs="$merc_shlib_dirs $LIBDIR/$GRADE/$FULLARCH"
 		merc_shlib_dirs="$merc_shlib_dirs $LIBDIR/$FULLARCH"
 		;;
 	static)
-		LIBS=${MERCURY_LIBS="\
-			$LIBDIR/$GRADE/$FULLARCH/lib$TRACE_LIB_NAME.a \
-			$LIBDIR/$GRADE/$FULLARCH/lib$BROWSER_LIB_NAME.a \
+		LIBS=${MERCURY_LIBS="$TRACE_STATIC_LIBS
 			$LIBDIR/$GRADE/$FULLARCH/lib$STD_LIB_NAME.a \
 			$LIBDIR/$GRADE/$FULLARCH/lib$RT_LIB_NAME.a \
 			$LIBGC_STATIC \
@@ -392,7 +437,6 @@
 		merc_shlib_dirs=""
 		;;
 esac
-LIBS=${LIBS}${SOCKET_LIBRARY}
 
 
 RPATH_OPT_LIST=

-- 
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.



More information about the developers mailing list