This PR fixes a bug on WSL (and potentially Linux) where the preprocessor is stuck in an indefinite loop. I've setup a repository to repro the issue which can be found here: https://github.com/JLWalsh/pawncc-wsl-bug-demo
What is the bug?
When processing includes, the preprocessor checks if the path is not a directory by calling stat() and then checking !S_ISDIR() on the result as we only want to load files. The current implementation does not check the result of stat(), which can fail. When this happens, the results of stat() cannot be trusted and the !S_ISDIR() check passes even when the path is a directory.
This causes the preprocessor to open a file descriptor pointing to a directory instead of a file. The compiler will then get stuck in a loop in the preprocess() function as readline() returns an empty line without moving the parser forward. This happens because readline() attempts to read the directory as a file, which naturally does not work.
By adding the result check on stat(), we can prevent the compiler from hanging indefinitely. However, the underlying issue causing stat() to fail is not fixed. In my testing I found that stat() fails with errno=75 (EOVERFLOW) because of a storage discrepancy caused by 32 bit executables running on a 64 bit machine. More details on this error can be found in the stat() manpage error section. The recommended fix is to define the _FILE_OFFSET_BITS flag which worked on my machine
Why doesn't this happen on Windows?
This is down to a difference in behaviour of fgets() between Windows and WSL. The readline() function loads the included file line by line using fgets(). When calling fgets() with a directory on Linux, a file handle is returned. On Windows, I found that it would simply return NULL, which kept the compiler running as expected
Testing
I've tested the compiler on the sample project I've linked and it works after applying this bugfix. I'm not sure what other means of testing this project has, but I'd be happy to run more tests if need be
TL;DR
This PR fixes a bug on WSL (and potentially Linux) where the preprocessor is stuck in an indefinite loop. I've setup a repository to repro the issue which can be found here: https://github.com/JLWalsh/pawncc-wsl-bug-demo
What is the bug?
When processing includes, the preprocessor checks if the path is not a directory by calling
stat()
and then checking!S_ISDIR()
on the result as we only want to load files. The current implementation does not check the result ofstat()
, which can fail. When this happens, the results ofstat()
cannot be trusted and the!S_ISDIR()
check passes even when the path is a directory.This causes the preprocessor to open a file descriptor pointing to a directory instead of a file. The compiler will then get stuck in a loop in the
preprocess()
function asreadline()
returns an empty line without moving the parser forward. This happens becausereadline()
attempts to read the directory as a file, which naturally does not work.By adding the result check on
stat()
, we can prevent the compiler from hanging indefinitely. However, the underlying issue causingstat()
to fail is not fixed. In my testing I found thatstat()
fails witherrno=75 (EOVERFLOW)
because of a storage discrepancy caused by 32 bit executables running on a 64 bit machine. More details on this error can be found in thestat()
manpage error section. The recommended fix is to define the_FILE_OFFSET_BITS
flag which worked on my machineWhy doesn't this happen on Windows?
This is down to a difference in behaviour of
fgets()
between Windows and WSL. Thereadline()
function loads the included file line by line usingfgets()
. When callingfgets()
with a directory on Linux, a file handle is returned. On Windows, I found that it would simply returnNULL
, which kept the compiler running as expectedTesting
I've tested the compiler on the sample project I've linked and it works after applying this bugfix. I'm not sure what other means of testing this project has, but I'd be happy to run more tests if need be
Which issue(s) this PR fixes:
Not sure if this has been reported before
Fixes #
Additional Documentation:
Repro repo: https://github.com/JLWalsh/pawncc-wsl-bug-demo