[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Bug with double slashes
Re: Bug with double slashes
Sat, 06 Jun 2009 02:01:03 -0400
On Fri, 2009-06-05 at 00:46 -0400, Paul Smith wrote:
> > //%: //%
> > @echo oops!
> When I run this with GNU make 3.80, I get this error:
> make: Circular /tmp/x1.mk <- /tmp/x1.mk dependency dropped.
> Is that what you mean by "normal"?
> I do agree that something is broken in the circular prerequisite
> detection in 3.81 (and even in current CVS) because these versions of
> make don't notice the circularity and tries to continuously to create
> a new dependency until it goes over some limit
OK, I've investigated this. It's a bizarre confluence of different
First up, there's apparently a bug in the current glibc implementation
of glob(3) on my system. When I run glob() and pass it the pattern
"//%" and the GLOB_NOCHECK option, which is how GNU make invokes it in
this situation, it should (according to the POSIX standard) return the
input pattern unmodified (since the glob pattern doesn't match
anything--I'm assuming that you, like me, do not have a file "/%" on
However, what it ACTUALLY does is return "/%", stripping off the initial
"/". So, when make internalizes this pattern instead of storing the
string "//%" as the pattern, it's storing "/%" and that's why /tmp/x1.mk
is matching. It's even weirder because if you use something like "///%"
then you get back the right thing ("///%"). If you use "//%/" you get
back the right thing. It's only two slashes followed by a word (no more
slashes) that you get this bug.
If you have an implementation of glob() that more carefully follows the
POSIX standard then you'll get "//%" and your version of make could
behave differently, and you won't get the circular dependency dropped
error like I did.
So, that's the first thing.
The second thing is why you get the circular dep error in 3.80 and
basically an infinite loop in 3.81.
In 3.80, GNU make also ran the glob() function over the prerequisites,
which also stripped off the leading "/", so REALLY what I get with that
/% : /%
and it's obvious why there's a circular dep error.
However, as part of the second expansion code, BorisK deferred the
glob() call on the prerequisites list until later. Then apparently (I
didn't track this in detail) for pattern rules the glob() is never
actually run. In a way this makes sense since globbing a pattern is not
what you want.
But because of this, the prerequisite path is never "sanitized" to
remove the leading duplicate "/", and so in 3.81 and above this rule
/% : //%
Well, now you can clearly see why we are getting infinite recursion
Less obvious is which of the various ways it could be fixed is the right
way. Should we stop "cleaning" these paths altogether, to work around
the bug in glibc glob()? I think if we removed the GLOB_NOCHECK flag
from glob() then handled the GLOB_NOMATCH error correctly we could avoid
that problem. Should we go back to globbing the patterns? Seems like
overkill to me, and potentially wrong.
Paul D. Smith <address@hidden> Find some GNU make tips at:
"Please remain calm...I may be mad, but I am a professional." --Mad Scientist