URL: <http://savannah.gnu.org/bugs/?23960>
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 _______________________________________________________ Details: 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: <http://savannah.gnu.org/bugs/?23960> _______________________________________________ Message sent via/by Savannah http://savannah.gnu.org/ _______________________________________________ Bug-make mailing list Bug-make@gnu.org http://lists.gnu.org/mailman/listinfo/bug-make