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