[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #23960] Crash when MAKEFILE_LIST becomes too long.

From: Timothy N Murphy
Subject: [bug #23960] Crash when MAKEFILE_LIST becomes too long.
Date: Tue, 29 Jul 2008 11:52:55 +0000
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/2008070208 Firefox/3.0.1


                 Summary: Crash when MAKEFILE_LIST becomes too long.
                 Project: make
            Submitted by: tnmurphy
            Submitted on: Tuesday 07/29/2008 at 11:52
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
       Component Version: 3.81
        Operating System: MS Windows
           Fixed Release: None



I am working on a project which generates huge makefiles. These makefiles
include others many many times - there are perhaps 12,000 instances of the
"include" statement at a rough guess.

We found that GNU Make crashed on Windows and it took us a while to realise
that MAKEFILE_LIST was the problem.  We worked around it by setting
MAKEFILE_LIST to "blank" after every include statement, since we don't need
its value.

It turns out that the routine in make that appends to variables uses alloca
and it does appends in such a way that I imagine the mechanism for stack
expansion (the guard page) is being defeated.

The location is in do_variable_definition():

            oldlen = strlen (v->value);
            vallen = strlen (val);
            p = (char *) alloca (oldlen + 1 + vallen + 1);
            bcopy (v->value, p, oldlen);
            p[oldlen] = ' ';
            bcopy (val, &p[oldlen + 1], vallen + 1);

This copies the old value to the alloca'd block then adds a space and copies
the new value.

The problem is that stack grows down so if 'old_len' is larger than the guard
page, then the first memory access by bcopy to 'p' could occur below the guard
page.  This will not trigger the expansion of the stack.

The problem might happen with any variable that grows sufficiently large.

It's not easy to come up with a perfect fix for this and the obvious ones
such as using the heap would slow down the common case.  There are also no
memory copy routines that work from high to low addresses which would
obviously be ideal.

An initial suggestion might be something like this:
            bcopy (val, &p[oldlen + 1], vallen + 1);
            p[oldlen] = ' ';
            bcopy (v->value, p, oldlen);

Where by swapping the bcopy()s one improves the chance that the guard page
will be triggered (initialise high to low).  One might even split the bcopies
into loops that always copy less than the minimum page size and move down.

Our use case is extreme and there is a workaround so I don't suggest that
there is an immediate need to change this but it is worth noting in case
anyone else has the same problem.


Reply to this item at:


  Message sent via/by Savannah

reply via email to

[Prev in Thread] Current Thread [Next in Thread]