Hi, The attached patch against make-3.80 fixes a mysterious segfault that occurred when I tried to regenerate a file that dependend on a lot of other files.
The total length of these prerequisite filenames was somewhat more than 1MB. As it turns out, the use of alloca() for such a large data set in the function set_file_variables() caused a stack overflow. This is also because on my Linux system, make is implicitly linked against libpthread, which means that the maximum stacksize per thread is limited to 2MB. (A similar patch against make-3.79.1 is available on request.) Thanks, - Wil Wil Evers, DOOSYS R&D, Utrecht, Holland
*** make-3.80/commands.c Tue Oct 8 16:50:51 2002 --- make/commands.c Wed Oct 9 12:38:16 2002 *************** *** 35,40 **** --- 35,45 ---- #ifndef HAVE_UNISTD_H extern int getpid (); #endif + + #define PLUS_BUF_SIZE 0x10000 + #define QMARK_BUF_SIZE 0x10000 + #define BAR_BUF_SIZE 0x10000 + /* Set FILE's automatic variables up. */ *************** *** 128,136 **** --- 133,144 ---- { unsigned int qmark_len, plus_len, bar_len; + char plus_buf[PLUS_BUF_SIZE]; char *caret_value, *plus_value; char *cp; + char qmark_buf[QMARK_BUF_SIZE]; char *qmark_value; + char bar_buf[BAR_BUF_SIZE]; char *bar_value; char *qp; char *bp; *************** *** 147,153 **** if (plus_len == 0) plus_len++; ! cp = plus_value = (char *) alloca (plus_len); qmark_len = plus_len + 1; /* Will be this or less. */ for (d = file->deps; d != 0; d = d->next) --- 155,166 ---- if (plus_len == 0) plus_len++; ! if (plus_len <= PLUS_BUF_SIZE) { ! plus_value = plus_buf; ! } else { ! plus_value = (char *) xmalloc(plus_len); ! } ! cp = plus_value; qmark_len = plus_len + 1; /* Will be this or less. */ for (d = file->deps; d != 0; d = d->next) *************** *** 193,200 **** /* Compute the values for $^, $?, and $|. */ cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */ ! qp = qmark_value = (char *) alloca (qmark_len); ! bp = bar_value = (char *) alloca (bar_len); for (d = file->deps; d != 0; d = d->next) { --- 206,225 ---- /* Compute the values for $^, $?, and $|. */ cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */ ! ! if (qmark_len <= QMARK_BUF_SIZE) { ! qmark_value = qmark_buf; ! } else { ! qmark_value = (char *) xmalloc(qmark_len); ! } ! qp = qmark_value; ! ! if (bar_len <= BAR_BUF_SIZE) { ! bar_value = bar_buf; ! } else { ! bar_value = (char *) xmalloc(bar_len); ! } ! bp = bar_value; for (d = file->deps; d != 0; d = d->next) { *************** *** 240,245 **** --- 265,280 ---- bp[bp > bar_value ? -1 : 0] = '\0'; DEFINE_VARIABLE ("|", 1, bar_value); + + if (bar_value != bar_buf) { + free(bar_value); + } + if (qmark_value != qmark_buf) { + free(qmark_value); + } + if (plus_value != plus_buf) { + free(plus_value); + } } #undef DEFINE_VARIABLE