[Top][All Lists]

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

Environment gets zapped on makefile re-read

From: Andre Sihera
Subject: Environment gets zapped on makefile re-read
Date: Sun, 04 Sep 2005 01:07:44 +0100


First may I apologise for this long post. However, I thought it best to be
thorough in my explanation so hopefully someone might be able to help. Thanks
in advance for bearing with me.

I am experiencing a bug on Win32 and I was wondering if anyone has experienced
this problem on any other platform. There is nothing in the bug archives regarding the problem so I am appealing for help. For this reason, I have cross-posted this
bug-report to both the generic bug mailing list and the Win32 specific mailing
list. Apologies if this is against protocol.


It appears that when a makefile is re-read (for example, as the result of an
included makefile having been updated), the environment for the spawned process
that handles the makefile re-read gets completely wiped out. There are no
environment variables defined in the environment of the spawned process.

This causes a number of errors, including the fact that all tools referenced from
within the re-read makefile are no longer accessible as the "Path" variable (as
well as all other variables) have disappeared.

It is a completely random bug and I have found no reproduce-able circumstances
whatsoever, except that if a makefile executes and does not need re-reading then the described behaviour has not been seen to happen. The following makefile shows how the problem can be highlighted, although because the bug is random, whether it reproduces the problem for you depends on how long you're prepared to sit around
and test it.

---------------------------------------------------------------- Environment start
------------------------------------------------------------------ Environment end

----------------------------------------------------------------- "Makefile" start
$(warning BUILDSYS [$(BUILDSYS)])
include $(BUILDSYS)/Core.inc
$(warning BUILDSYS [$(BUILDSYS)])
------------------------------------------------------------------- "Makefile" end

----------------------------------------------------------------- "Core.inc" start
-include depends.inc

all: foo.exe

foo.exe: foo.obj
        ilink32 $^ c0x32.obj,$@,,import32.lib cw32mt.lib,,

%.obj: %.c
        bcc32 $< -o$@

        echo foo.c: foo.h >$@

        for %%i in (foo.exe foo.obj depends.inc) do @if exist %%i del %%i
------------------------------------------------------------------- "Core.inc" end

The output from this makefile if it executes ok is as follows:

Makefile:1: BUILDSYS [C:\BuildSystem]
Makefile:3: BUILDSYS [C:\BuildSystem]
echo foo.c: foo.h >depends.inc
Makefile:1: BUILDSYS [C:\BuildSystem]
Makefile:3: BUILDSYS [C:\BuildSystem]
... foo.exe compilation output

However, the output from this makefile if it fails is as follows:

Makefile:1: BUILDSYS [C:\BuildSystem]
Makefile:3: BUILDSYS [C:\BuildSystem]
echo foo.c: foo.h >depends.inc
Makefile:1: BUILDSYS []
Makefile:2: /Core.inc: No such file or directory

make.exe: *** No rule to make target `/Core.inc'.  Stop.

The situation is fairly obvious: when the makefile is first read the core makefile "Core.inc" is read from the directory "C:\BuildSystem". This in turn includes the
file "depends.inc" in the current directory, required for building "foo.exe."

However, when depends.inc is updated, the makefile is re-read, and the reexecution fails because the environment variable BUILDSYS has disappeared causing "Core.inc"
to become inaccessible.


Some investigation into the problem led me to file a "variable.c" within the make build, and the function "sync_Path_environment" which does what I consider to be a slightly dodgy operation with "putenv" and some malloc'd memory. I use Borland C++ and their documentation is categorical about "putenv", and the string that is
allowed to be passed to the function, stating that the string should not be
malloc'd as subsequent frees could cause the environment to get corrupted. In the function "sync_Path_environment" the memory for the "Path" definition is malloc'd, then freed the next time the function is called. As the function is called every time a command gets executed in a rule, this function is called a good number of
times and so the environment could well be getting corrupted.

The latest version of "variable.c" in the CVS archives contains exactly the same
function as the version of make I am using (3.81 beta 2), but whilst I suspect
that the problem might be in this area I don't want to dive in until I am sure
that no-one else has seen or fixed this problem before.

Any comments and questions are appreciated.

Kind Regards,

Andre Sihera.

=================================================================== "putenv" start


#include <stdlib.h>
int putenv(const char *name);
int _wputenv(const wchar_t *name);


Adds string to current environment.

putenv accepts the string name and adds it to the environment of the current
process. For example,


putenv can also be used to modify an existing name. On DOS and OS/2, name must be uppercase. On other systems, name can be either uppercase or lowercase. name must
not include the equal sign (=). You can set a variable to an empty value by
specifying an empty string on the right side of the '=' sign.

putenv can be used only to modify the current program's _environment. Once the
program ends, the old _environment is restored. The _environment of the current
process is passed to child processes, including any changes made by putenv.

Note that the string given to putenv must be static or global. Unpredictable
results will occur if a local or dynamic string given to putenv is used after the
string memory is released.

Return Value

On success, putenv returns 0; on failure, -1.

===================================================================== "putenv" end

reply via email to

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