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