[gnu.utils.bug] possible bug in Make-3.54

davide%cadillac.cad.mcc.com@MCC.COM (David Eckelkamp) (07/07/89)

Program:  GNU Make
Version:  3.54
Machines: Sun3 and Sun4 running SunOS 4.0.1

Symptom:
    Make dumps core with a "Bus Error" on a simple makefile

Cause:
    The "$foreach()" function with a variable as one of its arguments
    causes a core dump. Apparently, the hash table for variables is
    being corrupted (actually it is not initialized).

Sample Makefile:
================
LIB =	../libdms.a

SRCS =	access.c basicio.c copy.c descriptor.c dirs.c \
	fileops.c move.c paths.c remove.c import-export.c
OBJS =  $(SRCS:.c=.o)
BUILD_LIB = $(patsubst %.c,$(LIB)(%.o),$(member))
LIB_MEMBERS := $(foreach member,$(SRCS),$(BUILD_LIB))

all:
	echo "SRCS = $(SRCS)" \
	echo "OBJS = $(OBJS)" \
	echo "BUILD_LIB = $(BUILD_LIB)" \
	echo "LIB_MEMBERS = $(LIB_MEMBERS)"
================

Detailed Description:
    In the file function.c, in function expand_function, in the case
    function_foreach in the switch on function there a call to
    push_new_variable_scope followed by a call to define_variable
    (about line 579). The memory allocated by push_new_variable_scope
    is not cleared, it is justed malloced from the heap and contains
    what ever info was stored there last. Then in
    define_variable_in_set (called from the only line in
    define_variable) you will find the fragment: 

      for (v = set->table[hashval]; v != 0; v = v->next)
	if (*v->name == *name
	    && !strncmp (v->name + 1, name + 1, length - 1)
	    && v->name[length] == '\0')
	  break;

    Here "set" is the memory that was malloced up in
    push_new_variable_scope and it has not been altered before this.  The
    variable v is supposed to get set to the first entry in the chain of
    the appropriate hash bucket and then the chain will be searched to see
    if a variable has already been set that has that name. Since
    set->table contains garbage, the "v != 0" test is true so the body of
    the loop gets executed. At this point, v is not NULL, and it is not a
    valid pointer and so we get a "Bus Error".

Possible Cure:
    For me, the cure was to zero the memory for the hash table after
    it is malloc'ed in push_new_variable_scope. It allowed the test
    makefile to execute. Here is the context diff of the fix. It could be
    done more efficiently, but hey, what are optimizing compilers for :-)

diff -c variable.c.de variable.c
*** variable.c.de       Sun Jun 11 14:25:51 1989
--- variable.c  Thu Jul  6 13:29:12 1989
***************
*** 254,259 ****
--- 254,260 ----
    set->buckets = SMALL_SCOPE_VARIABLE_BUCKETS;
    set->table = (struct variable **)
      xmalloc (set->buckets * sizeof (struct variable *));
+   (void) memset(set->table, 0, set->buckets * sizeof (struct variable *));

    setlist = (struct variable_set_list *)
      xmalloc (sizeof (struct variable_set_list));


David Eckelkamp         
ARPA: eckelkamp@mcc.com
uucp: {uunet|harvard|gatech|pyramid}!cs.utexas.edu!milano!cadillac!davide
Microelectronics and Computer Technology Corp. (MCC) VLSI CAD Program
3500 W.Balcones Center Dr., Austin,TX 78759            [512] 338-3796