Subject: make dumps core when invoked on large Makefile Index: bin/make 2.11BSD Description: When 'make' was invoked on the C-Kermit(5A) Makefile it would dump core due to the stack underflowing. Repeat-By: Get C-Kermit(5A) and "make bsd210ov" (after setting up an overlay configuration,etc). Observe the "Stop. core dumped" error. Fix: 'make' being heavily recursive does not work well with large buffers being allocated on the stack. There were several pathname buffers still allocated as BUFSIZ (1024) bytes long, these were reduced to MAXPATHLEN (256). A slight downsizing of the OUTMAX parameter (from 2500 to 2300) was also done (the docom() routine allocates 2 of these buffers on the stack!). Even a 'make' of the kernel does not use more than about 1300 bytes in the docom() buffers so a slight downsizing is safe. Other small changes to reduce the amount of local data on the stack involve placing variables in registers, reducing flag variables to 'char' instead of 'int', etc. The maximum number of arguments to execvp() was reduced from 400 to 254 and the table made static to further reduce the stack requirements. This reduction is possible because execvp() can only handle 254 (in the case of invoking a shell script) arguments anyhow. The vpath_exp buffer was reduced to the maximum pathlength size (from INMAX) and made static to further reduce the stack requirements. Finally the Makefile was reorganized to use 'xstr' to share strings and the silly sccs strings were commented out, this reduces the overall data space growth to about 400 bytes. These fixes do not forever fix 'make', but they do allow it to handle the C-Kermit(5A) Makefile (about 1400 lines). ------------------------------------------------------------------------ *** Makefile.old Wed Dec 19 13:25:25 1990 --- Makefile Sat Aug 10 14:49:49 1991 *************** *** 4,27 **** OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o LIBES= LINT= lint -ps # 2.11BSD uses the newer ascii format archives, not the old binary format CFLAGS= -O -DASCARCH -I. # CFLAGS= -O -I. SEPFLAG= -i all: make ! make: ${OBJECTS} ! ${CC} -o make ${CFLAGS} ${SEPFLAG} ${OBJECTS} ${LIBES} ${OBJECTS}: defs clean: ! -rm -f *.o gram.c make a.out errs install: install -s make ${DESTDIR}/bin/make lint : dosys.c doname.c files.c main.c misc.c ident.c gram.c ! ${LINT} dosys.c doname.c files.c main.c misc.c ident.c gram.c rm -f gram.c --- 4,46 ---- OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o LIBES= LINT= lint -ps + XSTR= /usr/ucb/xstr # 2.11BSD uses the newer ascii format archives, not the old binary format CFLAGS= -O -DASCARCH -I. # CFLAGS= -O -I. SEPFLAG= -i + # Special massaging of C files for sharing of strings + .c.o: + ${CC} -E ${CFLAGS} $*.c | ${XSTR} -c - + ${CC} -c ${CFLAGS} x.c + mv -f x.o $*.o + rm -f x.c + all: make ! make: ${OBJECTS} strings.o ! ${CC} -o make ${CFLAGS} ${SEPFLAG} ${OBJECTS} strings.o ${LIBES} ${OBJECTS}: defs clean: ! -rm -f *.o gram.c make a.out errs x.c xs.c strings install: install -s make ${DESTDIR}/bin/make lint : dosys.c doname.c files.c main.c misc.c ident.c gram.c ! ${LINT} -DASCARCH dosys.c doname.c files.c main.c misc.c ident.c gram.c rm -f gram.c + + gram.c: gram.y + yacc gram.y + fgrep -v "static char yaccpar_sccsid" y.tab.c >gram.c + rm -f y.tab.c + + strings.o: strings + ${XSTR} + ${CC} -c xs.c + mv -f xs.o strings.o + rm -f xs.c *** defs.old Sat Jul 8 19:46:48 1989 --- defs Sun Aug 11 15:04:37 1991 *************** *** 27,34 **** #define NLEFTS 80 #define NCHARS 500 #define NINTS 250 ! #define INMAX 1500 ! #define OUTMAX 2500 #define MAXDIR 10 #else !BSD2_10 #define HASHSIZE 1021 --- 27,34 ---- #define NLEFTS 80 #define NCHARS 500 #define NINTS 250 ! #define INMAX 1350 ! #define OUTMAX 2300 #define MAXDIR 10 #else !BSD2_10 #define HASHSIZE 1021 *** doname.c.old Sat Jul 8 18:04:47 1989 --- doname.c Wed Aug 14 08:32:46 1991 *************** *** 20,27 **** TIMETYPE *tval; { int errstat; ! int okdel1; ! int didwork; TIMETYPE td, td1, tdep, ptime, ptime1, prestime(); register struct depblock *q; struct depblock *qtemp, *srchdir(), *suffp, *suffp1; --- 20,27 ---- TIMETYPE *tval; { int errstat; ! u_char okdel1; ! u_char didwork; TIMETYPE td, td1, tdep, ptime, ptime1, prestime(); register struct depblock *q; struct depblock *qtemp, *srchdir(), *suffp, *suffp1; *************** *** 30,36 **** register struct lineblock *lp; struct lineblock *lp1, *lp2; #ifdef BSD2_10 ! char sourcename[256], prefix[256], temp[256], concsuff[20]; #else char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20]; #endif --- 30,39 ---- register struct lineblock *lp; struct lineblock *lp1, *lp2; #ifdef BSD2_10 ! /* temp and sourcename are mutually exclusive - save 254 bytes of stack by ! * reusing sourcename's buffer ! */ ! char sourcename[256], prefix[256], *temp = sourcename, concsuff[20]; #else char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20]; #endif *************** *** 47,65 **** * was that, while macro expansion got done, the .c files in the * non-local directories wouldn't be found. */ ! struct varblock *vpath_cp, *varptr(); ! static int vpath_first; ! char vpath_exp[INMAX]; ! if (!vpath_first) { ! vpath_first = 1; vpath_cp = varptr("VPATH"); if (vpath_cp->varval) { subst(vpath_cp->varval, vpath_exp); ! setvar("VPATH",vpath_exp); } } } if(p == 0) { *tval = 0; --- 50,68 ---- * was that, while macro expansion got done, the .c files in the * non-local directories wouldn't be found. */ ! static struct varblock *vpath_cp; ! struct varblock *varptr(); ! static char vpath_exp[256]; ! if (!vpath_cp) { vpath_cp = varptr("VPATH"); if (vpath_cp->varval) { subst(vpath_cp->varval, vpath_exp); ! setvar("VPATH", vpath_exp); } } } + if(p == 0) { *tval = 0; *************** *** 160,166 **** if (savenamep) pnamep = ".a"; ! srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL); for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) { --- 163,169 ---- if (savenamep) pnamep = ".a"; ! srchdir( concat(prefix,"*",temp), NO, (struct depblock *) NULL); for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) { *************** *** 246,254 **** docom(q) struct shblock *q; { ! char *s; struct varblock *varptr(); ! int ign, nopr; char string[OUTMAX]; char string2[OUTMAX]; --- 249,257 ---- docom(q) struct shblock *q; { ! register char *s; struct varblock *varptr(); ! register int ign, nopr; char string[OUTMAX]; char string2[OUTMAX]; *** dosys.c.old Fri Aug 9 17:39:46 1991 --- dosys.c Fri Aug 9 17:57:46 1991 *************** *** 92,104 **** ! #define MAXARGV 400 doexec(str) register char *str; { register char *t; ! char *argv[MAXARGV]; register char **p; while( *str==' ' || *str=='\t' ) --- 92,104 ---- ! #define MAXARGV 254 /* execvp can only handle 254 anyhow */ doexec(str) register char *str; { register char *t; ! static char *argv[MAXARGV]; /* docom() ate most of the stack already */ register char **p; while( *str==' ' || *str=='\t' ) *** files.c.old Sat Jul 8 18:07:59 1989 --- files.c Wed Aug 14 08:40:03 1991 *************** *** 194,210 **** int mkchain; /* nonzero if results to be remembered */ struct depblock *nextdbl; /* final value for chain */ { ! DIR *dirf; ! register int i; ! int nread, cldir; ! char *dirname, *dirpref, *endir, *filepat, *p, temp[BUFSIZ]; ! char fullname[BUFSIZ], *p1, *p2; struct nameblock *q; struct depblock *thisdbl; struct dirhdr *od; struct pattern *patp; struct varblock *cp, *varptr(); ! char *path, pth[BUFSIZ], *strcpy(); struct direct *dptr; --- 194,209 ---- int mkchain; /* nonzero if results to be remembered */ struct depblock *nextdbl; /* final value for chain */ { ! register DIR *dirf; ! int cldir; ! char *dirname, *dirpref, *endir, *filepat, *p, temp[MAXPATHLEN]; ! char fullname[MAXPATHLEN], *p1, *p2; struct nameblock *q; struct depblock *thisdbl; struct dirhdr *od; struct pattern *patp; struct varblock *cp, *varptr(); ! char *path, pth[MAXPATHLEN], *strcpy(); struct direct *dptr; *************** *** 606,612 **** { if (fread(&objentry, sizeof(objentry), 1, arfd) != 1) return (0); ! if (objentry.n_type == N_EXT | N_TEXT && !strncmp(objentry.n_name, s, 8)) return (1); } --- 605,611 ---- { if (fread(&objentry, sizeof(objentry), 1, arfd) != 1) return (0); ! if ((objentry.n_type == (N_EXT | N_TEXT)) && !strncmp(objentry.n_name, s, 8)) return (1); } *************** *** 696,702 **** { register char *r, *q; struct nameblock *pn; ! char name[BUFSIZ]; while (*s) { if (isspace(*s)) *d++ = *s++; --- 695,701 ---- { register char *r, *q; struct nameblock *pn; ! char name[MAXPATHLEN]; while (*s) { if (isspace(*s)) *d++ = *s++; *** gram.y.old Sun Feb 8 17:24:38 1987 --- gram.y Sun Aug 11 15:24:59 1991 *************** *** 1,5 **** %{#include "defs" ! static char *sccsid = "@(#)gram.y 4.1 (Berkeley) 81/02/28"; %} %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER --- 1,5 ---- %{#include "defs" ! /* static char *sccsid = "@(#)gram.y 4.1 (Berkeley) 81/02/28"; */ %} %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER *** ident.c.old Thu Aug 8 18:18:41 1991 --- ident.c Thu Aug 8 18:19:03 1991 *************** *** 1,4 **** ! char *xxxvers = "\n@(#) MAKE. VERSION 2.61 13 AUGUST 1980\n" ; /* static char *sccsid = "@(#)ident.c 4.1 (Berkeley) 81/02/28"; */ /* --- 1,4 ---- ! /* char *xxxvers = "\n@(#) MAKE. VERSION 2.61 13 AUGUST 1980\n" ; */ /* static char *sccsid = "@(#)ident.c 4.1 (Berkeley) 81/02/28"; */ /* *** main.c.old Sat Jul 8 18:09:16 1989 --- main.c Sat Aug 10 19:05:36 1991 *************** *** 56,66 **** char *argv[]; { register struct nameblock *p; ! int i, j; int descset, nfargs; TIMETYPE tjunk; char c, *s; ! static char onechar[2] = "X"; #ifdef unix int intrupt(); #endif --- 56,66 ---- char *argv[]; { register struct nameblock *p; ! register int i, j; int descset, nfargs; TIMETYPE tjunk; char c, *s; ! static char onechar[2] = 'X'; #ifdef unix int intrupt(); #endif