[tree-ssa mudflap] libmudflap improvements

Frank Ch. Eigler fche@redhat.com
Tue Aug 20 09:55:00 GMT 2002


Hi -

Committing:

2002-08-20  Frank Ch. Eigler  <fche@redhat.com>

	Option parsing improvements, region splitting bug fixes:
	* mf-heuristics.c (__mf_register_ro_sections): Add warned casts.
	* mf-runtime.h (heur_proc_map): New libmudflap option.
	* mf-runtime.c (__mf_set_default_options): Set it.
	(__mf_usage): Print default values/status.
	(__mf_process_opts): Support general "no-" option string prefix.
	(__mf_init): Print __mf_usage on unknown-option error.
	(__mf_register): Print trace message up front.
	Correct region splitting logic for case where a subregion disappears.
	Correct memory leak.
	(__mf_violation): Make even basic message conditional on option.

	Build cleanup:
	* Makefile.am (TESTS_ENVIRONMENT): Add -no-heur-proc-map.
	(clean-local): New target.
	(test/*x rules): Add -g CFLAGS.
	(CFLAGS): Add -freorder-blocks.
	(MFCONFIG_CFLAGS, INCLUDE): Remove unneeded settings.
	* Makefile.in: Regenerated.
	* Makefile, mf-config.h: Removed files.


Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/Makefile.am,v
retrieving revision 1.1.2.3
diff -w -s -u -p -r1.1.2.3 Makefile.am
--- Makefile.am	17 Aug 2002 00:52:35 -0000	1.1.2.3
+++ Makefile.am	20 Aug 2002 16:54:07 -0000
@@ -7,7 +7,7 @@
 AUTOMAKE_OPTIONS = 1.3 cygnus
 MAINT_CHARSET = latin1
 
-TESTS_ENVIRONMENT = MUDFLAP_OPTIONS='-mode-check -viol-abort'
+TESTS_ENVIRONMENT = MUDFLAP_OPTIONS='-mode-check -viol-abort -no-heur-proc-map'
 
 TESTS = test/fail1.x test/fail10.x test/fail11.x test/fail12.x				\
  test/fail13.x test/fail14.x test/fail15.x test/fail16.x test/fail17.x			\
@@ -25,11 +25,14 @@ test/%.c: test/%-frag.c test/mf-driver.c
 	@cat $< >> $@
 	@echo '}' >> $@
 
+clean-local:
+	rm -f $(TESTS)
+
 test/fail%.x: test/fail%.c
-	$(CC) -DSHOULD_FAIL -fmudflap -o $@ $<
+	$(CC) -DSHOULD_FAIL -rdynamic -fmudflap -g -o $@ $<
 
 test/pass%.x: test/pass%.c
-	$(CC) -DSHOULD_PASS -fmudflap -o $@ $<
+	$(CC) -DSHOULD_PASS -rdynamic -fmudflap -g -o $@ $<
 
 
 # SUBDIRS = 
@@ -40,16 +43,13 @@ lib_LTLIBRARIES = libmudflap.la
 
 # Compile flags that should be constant throughout the build, both for
 # SUBDIRS and for libmudflap in general.
-CFLAGS = -O2 -g
+CFLAGS = -O2 -g -freorder-blocks
 WARN_CFLAGS = $(WERROR) -fdiagnostics-show-location=once
 
 # Use common includes from acinclude.m4/LIBMUDFLAP_EXPORT_INCLUDES
 LIBMUDFLAP_INCLUDES =
 TOPLEVEL_INCLUDES =
 
-
-MFCONFIG_CFLAGS = -I $(srcdir) -include mf-config.h
-
 mf-runtime.o: mf-runtime.h
 mf-hooks.o: mf-runtime.h
 mf-heuristics.o: mf-runtime.h
@@ -58,13 +58,9 @@ libmudflap_la_SOURCES = \
 	mf-runtime.c \
 	mf-hooks.c \
 	mf-heuristics.c
-INCLUDES = \
-	$(MFCONFIG_CFLAGS)
 
 # libmudflap_la_LIBADD =
 # libmudflap_la_LDFLAGS = 
 
 libmudflap_la_DEPENDENCIES = $(libmudflap_la_LIBADD)
 
-# COMPILE = $(LIBTOOL) --tag CC --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(AM_CFLAGS) $(WARN_CFLAGS) $(MFCONFIG_CFLAGS)
-# LINK = $(LIBTOOL) --tag CC --mode=link $(CC) $(AM_CFLAGS) $(LDFLAGS) -o $@
Index: mf-heuristics.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-heuristics.c,v
retrieving revision 1.1.2.1
diff -w -s -u -p -r1.1.2.1 mf-heuristics.c
--- mf-heuristics.c	17 Aug 2002 00:52:35 -0000	1.1.2.1
+++ mf-heuristics.c	20 Aug 2002 16:54:07 -0000
@@ -33,7 +33,8 @@ __mf_register_ro_sections ()
 	  fprintf (stderr, "mf: (heuristics) cannot open /proc/self/maps\n");
 	  fprintf (stderr, "mf: (heuristics) registering 00-%p\n", &_end);
 	}
-      __mf_register (0, &_end, __MF_TYPE_GUESS, 
+      __mf_register ((uintptr_t) 0, (uintptr_t) &_end,
+		     __MF_TYPE_GUESS, 
 		     "(heuristic) static 0-__end region");
       return;
     }
@@ -50,7 +51,8 @@ __mf_register_ro_sections ()
 		  fprintf (stderr, "mf: (heuristics) registering static region %p-%p\n",
 			  low, high);
 		}
-	      __mf_register (low, (high-low), __MF_TYPE_GUESS, 
+	      __mf_register ((uintptr_t) low, (uintptr_t) (high-low),
+			     __MF_TYPE_GUESS, 
 			     "(heuristic) static read-only segment");
 	    } 
 
Index: mf-runtime.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.c,v
retrieving revision 1.1.2.4
diff -w -s -u -p -r1.1.2.4 mf-runtime.c
--- mf-runtime.c	17 Aug 2002 00:52:35 -0000	1.1.2.4
+++ mf-runtime.c	20 Aug 2002 16:54:07 -0000
@@ -73,6 +73,7 @@ __mf_set_default_options ()
   __mf_opts.backtrace = 4;
   __mf_opts.mudflap_mode = mode_check;
   __mf_opts.violation_mode = viol_nop;
+  __mf_opts.heur_proc_map = 1;
 }
 
 static struct option
@@ -96,14 +97,14 @@ options [] =
      "mudflaps populate object tree", 
      set_option, (int)mode_populate, (int *)&__mf_opts.mudflap_mode},    
     {"mode-check", 
-     "mudflaps check for memory violations (default)",
+     "mudflaps check for memory violations",
      set_option, (int)mode_check, (int *)&__mf_opts.mudflap_mode},
     {"mode-violate", 
      "mudflaps always cause violations (diagnostic)",
      set_option, (int)mode_violate, (int *)&__mf_opts.mudflap_mode},
     
     {"viol-nop", 
-     "violations do not change program execution (default)",
+     "violations do not change program execution",
      set_option, (int)viol_nop, (int *)&__mf_opts.violation_mode},
     {"viol-abort", 
      "violations cause a call to abort()",
@@ -133,9 +134,13 @@ options [] =
     {"optimize-object-tree", 
      "periodically optimize memory object tracking tree",
      set_option, 1, &__mf_opts.optimize_object_tree},
+    /* XXX: this should be sensitive to gcc --enable-threading= setting */
     {"multi-threaded", 
      "support multiple threads",
      set_option, 1, &__mf_opts.multi_threaded},
+    {"heur-proc-map", 
+     "support /proc/self/map heuristics",
+     set_option, 1, &__mf_opts.heur_proc_map},
 
     {"free-queue-length", 
      "queue N deferred free() calls before performing them",
@@ -168,22 +173,30 @@ __mf_usage ()
 	   "$ <mudflapped_program>\n"
 	   "\n"
 	   "where <options> is a space-separated list of \n"
-	   "any of the following:\n"
+	   "any of the following options.  Use `-no-OPTION' to disable options.\n"
 	   "\n");
 
   for (opt = options; opt->name; opt++)
     {
+      int default_p = (opt->value == * opt->target);
+
       switch (opt->type)
 	{
 	  char buf[128];
 	case set_option:
-	  fprintf (stderr, "-%-23.23s %s\n", opt->name, opt->description);
+	  fprintf (stderr, "-%-23.23s %s", opt->name, opt->description);
+	  if (default_p)
+	    fprintf (stderr, " [default]\n", opt->value);
+	  else
+	    fprintf (stderr, "\n");
 	  break;
 	case read_integer_option:
 	  strncpy (buf, opt->name, 128);
 	  strncpy (buf + strnlen (opt->name, 128), "=N", 2);
-	  fprintf (stderr, "-%-23.23s %s\n", buf, opt->description);
+	  fprintf (stderr, "-%-23.23s %s", buf, opt->description);
+	  fprintf (stderr, " [%d]\n", * opt->target);
 	  break;	  
+	default: abort();
 	}
     }
 
@@ -220,6 +233,14 @@ __mf_process_opts (char *optstr)
 	    
 	    for (opts = options; opts->name; opts++)
 	      {
+		int negate = 0;
+
+		if (strncmp (optstr, "no-", 3) == 0)
+		  {
+		    negate = 1;
+		    optstr = & optstr[3];
+		  }
+
 		if (strncmp (optstr, opts->name, 
 				     strlen (opts->name)) == 0)
 		  {
@@ -228,10 +249,13 @@ __mf_process_opts (char *optstr)
 		    switch (opts->type) 
 		      {
 		      case set_option:
+			if (negate)
+			  *(opts->target) = 0;
+			else
 			*(opts->target) = opts->value;
 			break;
 		      case read_integer_option:
-			if (*optstr == '=' && *(optstr+1))
+			if (! negate && (*optstr == '=' && *(optstr+1)))
 			  {
 			    optstr++;
 			    tmp = strtol (optstr, &nxt, 10);
@@ -241,6 +265,8 @@ __mf_process_opts (char *optstr)
 				*(opts->target) = (int)tmp;
 			      }
 			  }
+			else if (negate)
+			  * opts->target = 0;
 			break;
 		      }
 		  }
@@ -278,6 +304,7 @@ void __mf_init ()
 	  fprintf (stderr, 
 		   "mudflap error: unknown options in "
 		   "environment variable MUDFLAP_OPTIONS\n");
+	  __mf_usage ();
 	  exit (1);
 	}
     }
@@ -529,9 +556,12 @@ __mf_remove_old_object (__mf_object_tree
 void
 __mf_register (uintptr_t ptr, uintptr_t sz, int type, const char *name)
 {
-
   if (UNLIKELY (! __mf_active_p)) return;
 
+  if (__mf_opts.trace_mf_calls)
+    fprintf (stderr, "mf reg p=%08lx s=%lu t=%d n=`%s'\n", 
+	     ptr, sz, type, name ? name : "");
+
   switch (__mf_opts.mudflap_mode)
     {
     case mode_nop:
@@ -593,50 +623,54 @@ __mf_register (uintptr_t ptr, uintptr_t 
 		  {
 		    if (ovr_obj[i]->data.type == __MF_TYPE_GUESS)
 		      {
-
-			/* We're going to split our existing guess into 2
-			   and put this new region in the middle */
+			/* We're going to split our existing guess
+			   into 2 and put this new region in the
+			   middle. */
 			
 			uintptr_t guess1_low, guess1_high;
 			uintptr_t guess2_low, guess2_high;
 			uintptr_t guess_pc;
 			const char *guess_name;
+			extern void  __real_free (void *);
 			
 			guess_pc = ovr_obj[i]->data.alloc_pc;
 			guess_name = ovr_obj[i]->data.name;
 
 			guess1_low = ovr_obj[i]->data.low;
-			guess1_high = low - (1 + __mf_opts.crumple_zone);
+			guess1_high = CLAMPSUB (low, (1 + __mf_opts.crumple_zone));
 
-			guess2_low = high + (1 + __mf_opts.crumple_zone);
+			guess2_low = CLAMPADD (high, (1 + __mf_opts.crumple_zone));
 			guess2_high = ovr_obj[i]->data.high;
-
-			/* Correct for possible over-shoot on crumple zones. */
-			guess2_low = min (guess2_low, guess2_high);
-			guess1_high = max (guess1_high, guess1_low);
+			/* NB: split regions may disappear if low > high. */
 			
 			if (__mf_opts.trace_mf_calls)
 			  {
 			    fprintf (stderr, 
-				     "mf: splitting guess region from %p-%p to %p-%p and %p-%p\n", 
-				     guess1_low, 
-				     guess2_high, 
-				     guess1_low, 
-				     guess1_high, 
-				     guess2_low, 
-				     guess2_high);
+				     "mf: splitting guess region %08lx-%08lx\n",
+				     guess1_low, guess2_high);
 			  }
 			
-			__mf_remove_old_object (ovr_obj[i]);
+			__mf_unlink_object (ovr_obj[i]);
+			__real_free (ovr_obj[i]->data.alloc_backtrace);
+			/* __real_free (ovr_obj[i]->data.dealloc_backtrace); */
+			__real_free (ovr_obj[i]);
+			ovr_obj[i] = NULL;
+
+			/* XXX: preserve other information: stats? backtraces */
 
+			if (guess1_low <= guess1_high)
+			  {
 			__mf_insert_new_object (guess1_low, guess1_high, 
 						__MF_TYPE_GUESS, 
 						guess_name, guess_pc);
+			  }
 
+			if (guess2_low <= guess2_high)
+			  {
 			__mf_insert_new_object (guess2_low, guess2_high, 
 						__MF_TYPE_GUESS, 
 						guess_name, guess_pc);
-
+			  }
 		      }
 		    else
 		      {
@@ -667,10 +701,6 @@ __mf_register (uintptr_t ptr, uintptr_t 
 				(type > __MF_TYPE_GUESS) ? 0 : 
 				type] += sz;
     }
-
-  if (__mf_opts.trace_mf_calls)
-    fprintf (stderr, "mf reg p=%08lx s=%lu t=%d n=`%s'\n", 
-	     ptr, sz, type, name ? name : "");
 }
 
 /* }}} */
@@ -743,7 +773,7 @@ __mf_unregister (uintptr_t ptr, uintptr_
 
 	if (__mf_opts.trace_mf_calls)
 	  {
-	    fprintf (stderr, "mf: removing region %p-%p\n", old_obj->data.low, old_obj->data.high); 
+	    fprintf (stderr, "mf: removing region %08lx-%08lx\n", old_obj->data.low, old_obj->data.high); 
 	  }
 
 	__mf_remove_old_object (old_obj);
@@ -1068,7 +1098,7 @@ __mf_unlink_object2 (__mf_object_tree_t 
   else if (ptr->data.low > node->data.high)
     return __mf_unlink_object2 (ptr, & node->right);
   else
-    abort (); /* XXX: missing object */
+    abort (); /* XXX: missing object; should fail more gracefully. */
 }
 
 static void
@@ -1148,11 +1178,10 @@ __mf_find_dead_objects (uintptr_t low, u
 static void
 __mf_describe_object (__mf_object_t *obj)
 {
-
   if (UNLIKELY (! __mf_active_p)) return;
 
   fprintf (stderr,
-	   "mudflap object %p: name=`%s'\n"
+	   "mudflap object %08lx: name=`%s'\n"
 	   "bounds=[%08lx,%08lx] area=%s access-count=%u\n"
 	   "alloc time=%lu.%06lu pc=%08lx\n",
 	   obj, (obj->name ? obj->name : ""), obj->low, obj->high,
@@ -1302,8 +1331,10 @@ __mf_violation (uintptr_t ptr, uintptr_t
 			  type] ++;
 
   /* Print out a basic warning message.  */
-  /* XXX: should even this be conditional?  */
+  if (__mf_opts.verbose_violations)
   {
+    unsigned dead_p;
+    unsigned num_helpful = 0;
     struct timeval now;
     gettimeofday (& now, NULL);
 
@@ -1317,7 +1348,6 @@ __mf_violation (uintptr_t ptr, uintptr_t
 	      (type == __MF_VIOL_REGISTER) ? "register" :
 	      (type == __MF_VIOL_UNREGISTER) ? "unregister" :
 	      "unknown"));
-  }
 
   if (__mf_opts.backtrace > 0)
     {
@@ -1339,10 +1369,6 @@ __mf_violation (uintptr_t ptr, uintptr_t
       __real_free (symbols);
     }
 
-  if (__mf_opts.verbose_violations)
-  {
-    unsigned dead_p;
-    unsigned num_helpful = 0;
 
     /* Look for nearby objects.  For this, we start with s_low/s_high
        pointing to the given area, looking for overlapping objects.
Index: mf-runtime.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.h,v
retrieving revision 1.1.2.3
diff -w -s -u -p -r1.1.2.3 mf-runtime.h
--- mf-runtime.h	17 Aug 2002 00:52:35 -0000	1.1.2.3
+++ mf-runtime.h	20 Aug 2002 16:54:07 -0000
@@ -106,6 +106,8 @@ struct __mf_options
   }
   violation_mode;
   
+  /* Violation heuristics selection. */
+  int heur_proc_map;  /* Register /proc/self/map regions.  */
 };
 
 extern struct __mf_options __mf_opts;



More information about the Gcc-patches mailing list