Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#5753 closed bug (invalid)

ghci doesn't always use compiled modules

Reported by: rl Owned by:
Priority: normal Milestone: 7.4.1
Component: Compiler Version: 7.2.1
Keywords: Cc:
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: Other Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


Here is a small program:

module T where
foo :: Int -> Int
foo n = n+1
module U where
import T
main = print (foo 1)

Now I do this:

$ ghc -c T.hs
$ runhaskell -v U.hs
[1 of 2] Skipping  T                ( T.hs, T.o )
$ touch T.hs
$ runhaskell -v U.hs
[1 of 2] Compiling T                ( T.hs, interpreted )
$ ghc -c T.hs -fforce-recomp
$ runhaskell -v U.hs
[1 of 2] Compiling T                ( T.hs, interpreted )

Note that runhaskell doesn't use T.o even though I recompiled T. As far as I understand, this is because compilation has regenerated T.o but hasn't updated T.hi because the interface hasn't changed. So T.hi is older than T.hs and ghci seems to ignore the compiled version in this case. I'm not sure why the .hi file's timestamped is checked here, it seems that checking the .o file should be sufficient.

Change History (8)

comment:1 Changed 8 years ago by simonmar

difficulty: Unknown
Milestone: 7.4.1
Status: newinfoneeded

I can't reproduce this with ghc-7.2.1, 7.2.2, the current 7.4 branch or HEAD. What version are you using?

comment:2 Changed 8 years ago by simonmar

You might also try with -ddump-hi-diffs which will tell you why GHC is recompiling the module.

comment:3 Changed 8 years ago by rl

It happens for me and other people with 7.2.2 and I can reproduce it with a recent head. On Cygwin at least, you have to leave enough time between the steps (>1min) for the timestamps to be different (I should have mentioned that, sorry).

comment:4 Changed 8 years ago by rl

-ddump-hi-diffs says this in the last step:

    Source file changed or recompilation check turned off

comment:5 Changed 8 years ago by simonmar

I'm still trying to reproduce it. Here's what I'm using:

# GHC=/c/simonmar/ghc-validate/inplace/bin/ghc-stage2

rm -f *.hi *.o
$GHC -c T.hs
runhaskell -f $GHC -v U.hs
sleep 70
touch T.hs
runhaskell -f $GHC -v U.hs
sleep 70
$GHC -c T.hs -fforce-recomp
runhaskell -f $GHC -v U.hs

the last step always says "Skipping T". I haven't tried it with Cygwin yet, but I have tried with MSYS on Windows. Before I go to the trouble of installing Cygwin, have I got something wrong in the script here? Does that script reproduce it for you?

If it happens for you and not me, then my guess would be that something weird is going on with timestamps on your system, perhaps due to a virus scanner or somesuch.

comment:6 Changed 8 years ago by rl

Resolution: invalid
Status: infoneededclosed

Gosh, it turns out that for some reason, Cygwin's clock can be a couple of minutes ahead of the system clock so touching T.hs produces a timestamp in the future (based on Cygwin's clock) and even after recompiling, T.o has a timestamp before that (based on the system clock). So this indeed only happens under Cygwin and only under quite specific circumstances (although it seems that I'm not the only one for whom this happens).

I'll close the ticket but have you considered storing an hash of the source file in the .hi file and using that instead of the timestamps? It seems that would be more robust.

comment:7 Changed 8 years ago by simonmar

There is definitely something strange going on with times on Cygwin:

comment:8 Changed 8 years ago by rl

It seems that Cygwin, once initialised, keeps its own timer which is entirely independent from the system clock and slowly goes out of sync. This is on a per-app basis so closing all Cygwin shells (which, I assume, are just one app) and then opening the new one cures this for a while. This might also explain the effects Ian was seeing - Cygwin's timer was a bit ahead and both date and touch used it whereas non-Cygwin apps used the system time.

Here is a potentially relevant link, courtesy of Malcolm.

Note: See TracTickets for help on using tickets.