- Work around a bug in glibc glob(3), by avoiding GLOB_NOCHECK.

- Fix issue in very parallel builds found building glibc.
This commit is contained in:
Paul Smith 2009-06-06 23:16:46 +00:00
parent 71385e1225
commit b9f831b858
4 changed files with 87 additions and 68 deletions

View File

@ -1,3 +1,13 @@
2009-06-06 Paul Smith <psmith@gnu.org>
* remake.c (check_dep): Only set the target's state to not-started
if it's not already running. Found this while testing -j10 builds
of glibc: various targets were being rebuilt multiple times.
* read.c (multi_glob): Don't pass GLOB_NOCHECK to glob(3); instead
handle the GLOB_NOMATCH error. This is to work around Sourceware.org
Bugzilla bug 10246.
2009-06-04 Paul Smith <psmith@gnu.org>
* read.c (eval): Skip initial whitespace (ffeed, vtab, etc.)

129
read.c
View File

@ -3083,6 +3083,9 @@ multi_glob (struct nameseq *chain, unsigned int size)
for (old = chain; old != 0; old = nexto)
{
int r;
const char **nlist = 0;
int i = 0;
const char *gname;
#ifndef NO_ARCHIVES
char *arname = 0;
@ -3109,76 +3112,78 @@ multi_glob (struct nameseq *chain, unsigned int size)
}
#endif /* !NO_ARCHIVES */
switch (glob (gname, GLOB_NOCHECK|GLOB_ALTDIRFUNC, NULL, &gl))
r = glob (gname, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl);
switch (r)
{
case 0: /* Success. */
{
int i = gl.gl_pathc;
while (i-- > 0)
{
#ifndef NO_ARCHIVES
if (memname != 0)
{
/* Try to glob on MEMNAME within the archive. */
struct nameseq *found
= ar_glob (gl.gl_pathv[i], memname, size);
if (! found)
{
/* No matches. Use MEMNAME as-is. */
unsigned int alen = strlen (gl.gl_pathv[i]);
unsigned int mlen = strlen (memname);
char *name;
struct nameseq *elt = xmalloc (size);
memset (elt, '\0', size);
name = alloca (alen + 1 + mlen + 2);
memcpy (name, gl.gl_pathv[i], alen);
name[alen] = '(';
memcpy (name+alen+1, memname, mlen);
name[alen + 1 + mlen] = ')';
name[alen + 1 + mlen + 1] = '\0';
elt->name = strcache_add (name);
elt->next = new;
new = elt;
}
else
{
/* Find the end of the FOUND chain. */
struct nameseq *f = found;
while (f->next != 0)
f = f->next;
/* Attach the chain being built to the end of the FOUND
chain, and make FOUND the new NEW chain. */
f->next = new;
new = found;
}
}
else
#endif /* !NO_ARCHIVES */
{
struct nameseq *elt = xmalloc (size);
memset (elt, '\0', size);
elt->name = strcache_add (gl.gl_pathv[i]);
elt->next = new;
new = elt;
}
}
globfree (&gl);
free (old);
break;
}
case GLOB_NOSPACE:
fatal (NILF, _("virtual memory exhausted"));
break;
case 0:
/* Success. */
i = gl.gl_pathc;
nlist = (const char **)gl.gl_pathv;
break;
default:
old->next = new;
new = old;
/* Not a match or another error; keep this name. */
i = 1;
nlist = &gname;
break;
}
/* For each matched element, add it to the list. */
while (i-- > 0)
#ifndef NO_ARCHIVES
if (memname != 0)
{
/* Try to glob on MEMNAME within the archive. */
struct nameseq *found
= ar_glob (nlist[i], memname, size);
if (! found)
{
/* No matches. Use MEMNAME as-is. */
unsigned int alen = strlen (nlist[i]);
unsigned int mlen = strlen (memname);
char *name;
struct nameseq *elt = xmalloc (size);
memset (elt, '\0', size);
name = alloca (alen + 1 + mlen + 2);
memcpy (name, nlist[i], alen);
name[alen] = '(';
memcpy (name+alen+1, memname, mlen);
name[alen + 1 + mlen] = ')';
name[alen + 1 + mlen + 1] = '\0';
elt->name = strcache_add (name);
elt->next = new;
new = elt;
}
else
{
/* Find the end of the FOUND chain. */
struct nameseq *f = found;
while (f->next != 0)
f = f->next;
/* Attach the chain being built to the end of the FOUND
chain, and make FOUND the new NEW chain. */
f->next = new;
new = found;
}
}
else
#endif /* !NO_ARCHIVES */
{
struct nameseq *elt = xmalloc (size);
memset (elt, '\0', size);
elt->name = strcache_add (nlist[i]);
elt->next = new;
new = elt;
}
if (r == 0)
globfree (&gl);
free (old);
#ifndef NO_ARCHIVES
if (arname)
free (arname);

View File

@ -984,10 +984,11 @@ check_dep (struct file *file, unsigned int depth,
struct dep *lastd;
int deps_running = 0;
/* Reset this target's state so that we check it fresh. It could be
that it's already been checked as part of an order-only
/* If this target is not running, set it's state so that we check it
fresh. It could be it was checked as part of an order-only
prerequisite and so wasn't rebuilt then, but should be now. */
set_command_state (file, cs_not_started);
if (file->command_state != cs_running)
set_command_state (file, cs_not_started);
lastd = 0;
d = file->deps;

View File

@ -49,8 +49,11 @@ all:;@echo "$(SHELL) $$SHELL"
$extraENV{SHELL} = $mshell;
run_make_test("all: export SHELL := /./$mshell\n".'
all:;@echo "$(SHELL) $$SHELL"
', '', "/./$mshell /./$mshell");
run_make_test("
SHELL := /././$mshell
one: two
two: export SHELL := /./$mshell\n".'
one two:;@echo "$@: $(SHELL) $$SHELL"
', '', "two: /./$mshell /./$mshell\none: /././$mshell $mshell\n");
1;