Opened 13 years ago

Closed 2 years ago

Last modified 18 months ago

#365 closed bug (fixed)

GHC dies silently with faulty preprocessor

Reported by: josefs Owned by: Phyx-
Priority: normal Milestone: 8.0.1
Component: Compiler Version: 7.11
Keywords: Cc:
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: T365
Blocked By: Blocking:
Related Tickets: Differential Rev(s): Phab:D1256
Wiki Page:

Description (last modified by thomie)

This is perhaps a minor nuisance but I had to spend
quite some time to track down my bug. When ghc is given
a preprocessor which for some reason cannot execute
then ghc just dies silently without giving any
indication as to what the problem was. It would be nice
with a little message hinting at the problem on stderr.

Oh, and by the way, the -F flag doesn't have any
documentation. It is only mentioned together with -optF.

Change History (13)

comment:1 Changed 13 years ago by nobody

Logged In: NO 

This is on Windows, I presume?

On Linux, I get:

$ ghc -F -pgmF wibble -c hello.hs   
ghc-6.4: could not execute: wibble

comment:2 Changed 13 years ago by josefs

Logged In: YES 
user_id=307552

Indeed, this is on windows. It happens very easily when
working on cygwin. It is very natural to use a shell script
as a preprocessor which is what I was trying to do. But
since ghc is a windows program it doesn't know what a shell
script is. Hence the failure.

comment:3 Changed 13 years ago by simonmar

Status: assignedclosed
Logged In: YES 
user_id=48280

Fixed, thanks for the report.

comment:4 Changed 2 years ago by thomie

Architecture: Unknown/Multiple
Description: modified (diff)
Operating System: Windows
Owner: simonmar deleted
Resolution: Fixed
Status: closednew
Type of failure: None/Unknown
Version: 6.47.11

This is still an issue.

$ echo 'main = return ()' > hello.hs
$ touch wibble                          # The faulty preprocessor.
$ chmod +x wibble
$ ghc -F -pgmF ./wibble -c hello.hs     # Note: no error message.
$ echo $?                               # But the command failed.
1

This affects TEST=enum01 currently.

Compiling with -v shows:

*** Haskell pre-processor:
"./wibble" "hello.hs" "hello.hs" "C:\msys64\tmp\ghc3020_0\ghc3020_1.hspp"


Failed: "./wibble" "hello.hs" "hello.hs" "C:\msys64\tmp\ghc3020_0\ghc3020_1.hspp" ./wibble: runInteractiveProcess: invalid argument (Exec format error)
Last edited 2 years ago by thomie (previous) (diff)

comment:5 Changed 2 years ago by thomie

It seems the -pgmF flag is just plain broken on Windows (msys2). The following fails in the same way as wibble above:

$ echo 'cat $2 > $3' > preprocess
$ chmod +x preprocess
$ ghc -F -pgmF ./preprocess hello.hs
$ echo $?
$ 1
Last edited 2 years ago by thomie (previous) (diff)

comment:6 Changed 2 years ago by thomie

Oh, Phyx on #ghc says -pgmF requires a .bat file. Sure enough, then it works:

$ echo 'cat %2 > %3' > preprocess.bat
$ chmod +x preprocess.bat
$ ghc -F -pgmF ./preprocess.bat hello.hs
C:\msys64\tmp\test>cat "hello.hs"  1>"C:\msys64\tmp\ghc1556_0\ghc1556_1.hspp" 
$ echo $?
0

Still, I'd like to see an error message when preprocessing fails, without having to specify -v.

Last edited 2 years ago by thomie (previous) (diff)

comment:7 Changed 2 years ago by Phyx-

More specifically, I think the issue here is with the use of runInteractiveProcess, which ultimately calls CreateProcess on Windows. The problem is that processes created using CreateProcess must be known by the Windows loader. From the MSDN page.

"This module can be a Windows-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer. "

Since .py are not known by the system loader the call fails with Exec format error

I think there are two solutions:

  • Specify cmd.exe or rather, whatever ComSpec is pointing to as the application and the preprocessor to run as the argument.
  • Alternatively use ShellExecute instead of CreateProcess to start the preprocessors.

However both of them won't necessarily fix the tests that are failing, since that would require the .py extension to be registered to the python2 in msys.

comment:8 Changed 2 years ago by Phyx-

Differential Rev(s): Phab:D1256
Status: newpatch
Test Case: T365

Added a patch so it doesn't silently die.

comment:9 Changed 2 years ago by Phyx-

Owner: set to Phyx-

comment:10 Changed 2 years ago by Ben Gamari <ben@…>

In b6f76b9/ghc:

Prevent GHC from silently dying when preprocessor is not found

The Windows preprocessor code calls `runInteractiveProcess` but does
not check if an exception is thrown.
`runInteractiveProcess` calls `CreateProcess` which when given a format
the system loader does not know about
will throw an exception. This is what makes #9399 fail.

Ultimately we should not use any `CreateProcess` based calls but
instead `ShellExecuteEx` as  this would allow
us to run applications that the shell knows about instead of just the
loader. More details on #365.

This patch removes `PhaseFailed` and throws `ProgramError` instead.
`PhaseFailed` was largely unneeded since it never gave
very useful information aside from the `errorcode` which was almost
always `1`. `IOErrors` have also been eliminated and `GhcExceptions`
thrown in their place wherever possible.

Updates haddock submodule.

Test Plan:
`./validate` to make sure anything didn't break and
`make TESTS="T365"` to test that an error is now properly thrown

Reviewers: austin, thomie, bgamari

Reviewed By: thomie, bgamari

Subscribers: #ghc_windows_task_force

Differential Revision: https://phabricator.haskell.org/D1256

GHC Trac Issues: #365

comment:11 Changed 2 years ago by bgamari

Resolution: fixed
Status: patchclosed

Merged.

comment:12 Changed 23 months ago by thomie

Milestone: 8.0.1

comment:13 Changed 18 months ago by NeilMitchell

Using ShellExecute would probably be the wrong thing to do in this instance. ShellExecute is the right thing to "execute" (or Open) a file in the same way as the "Shell" (e.g. Windows Explorer) would do. In other words, its a generic "open this file" mechanism, not something to run command line tools, which is what you really want here.

Note: See TracTickets for help on using tickets.