Bug 30972

Summary: Call to _access has invalid parameter when linked with msvcrt (for vista)
Product: gcc Reporter: ska-pig
Component: driverAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: eric.weddington, fxcoudert, gabo143, gcc-bugs, ska-pig, zackw
Priority: P3    
Version: 4.1.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2007-03-25 18:23:55

Description ska-pig 2007-02-26 14:06:09 UTC
WinAVR, the AVR compiler package for Windows has some problems with Vista. I looked into it and think I have found the problem, which is in the GCC compiler and possibly in other parts of the GCC toolchain. 

The error shows up in any compilation with avr-gcc.exe:
 avr-gcc: _spawnvp: No such file or directory 

spawnvp is trying to spawn cc1.exe, but fails because it does not know where to find it. The argument to spawnvp is 'cc1', without any path. spawnv is tried first as well. The call comes from pex_win32_exec_child (libiberty/pex-win32.c). 

The problem is not spawnvp but the part that creates the correct path for cc1. I'm not sure where this code is (I only debugged the binary without source code), but I suspect it is the function find_a_file (gcc.c). The problem is project wide though.

What I do know is that when the possible cc1 paths are tested for existance, a call to the standard _access C function is used to test the paths. The problem is that the mode parameter is sometimes set to X_OK (system.h, equals 1). In unix like environments this tests for execute rights. However, when mingW is used to build GCC, the _access function from Microsoft's msvcrt.dll is used. This function does not allow the mode parameter to be 1. Only 0 (existance), 1 (write-only), 4 (read-only) or 6 (read-write). See: <http://msdn2.microsoft.com/en-us/library/1w06ktdy(VS.80).aspx>.

Earlier versions of msvcrt somehow ignored the invalid parameter and succeeded anyway. Newer versions, as found in Windows Vista do check for the invalid mode parameter and the function fails. GCC does not check for errors but falsely assumes that the file passed to _access does not exist. Therefore it does not find the correct cc1 path and subsequently the spawn fails.

The solution I think is to define X_OK as 0 on the MingW Windows platform. When the mode is 0 msvcrt's _access tests for existence. Which is pretty close to the execute right check.
Comment 1 Andrew Pinski 2007-03-25 18:23:03 UTC
*** Bug 31348 has been marked as a duplicate of this bug. ***
Comment 2 Andrew Pinski 2007-03-25 18:23:55 UTC
Confirmed.
Comment 3 Zack Weinberg 2007-05-10 08:36:47 UTC
What the heck are we doing calling access() in the first place?  We should just go ahead and try to execute .../cc1.exe for all relevant paths.
Comment 4 Francois-Xavier Coudert 2007-09-06 12:25:38 UTC
(In reply to comment #0)
> The problem
> is that the mode parameter is sometimes set to X_OK (system.h, equals 1).

X_OK is only defined in system.h if it's not defined by system includes. On mingw, X_OK happens to be defined by <io.h>.

> The solution I think is to define X_OK as 0 on the MingW Windows platform. When
> the mode is 0 msvcrt's _access tests for existence. Which is pretty close to
> the execute right check.

The mingw developers have modified their include files to work around this case, and you can get the old behaviour (X_OK is ignored) by compiling with -D__USE_MINGW_ACCESS (see PR33281). I intend to commit a patch that makes us build the compiler with -D__USE_MINGW_ACCESS, thus removing the problem.

I thus intend to close that PR. Zack, if you think we shouldn't use access() at all, do you want to keep this PR open and change its title to reflect this desired change?
Comment 5 Zack Weinberg 2007-09-06 17:35:13 UTC
Nah, probably no one will ever get round to it and it's not that important.
Comment 6 Francois-Xavier Coudert 2007-09-06 17:39:33 UTC

*** This bug has been marked as a duplicate of 33281 ***