Ticket #1176 (new bug)

Opened 6 years ago

Last modified 5 months ago

Infinite loop when printing error message

Reported by: Paul_Berry@… Owned by: thorkilnaur
Priority: low Milestone: _|_
Component: Compiler Version: 6.6
Keywords: Cc: dterei
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: tcfail177 Blocked By:
Blocking: Related Tickets:

Description

I am trying to compile a file that has a known compile error. Ghc gets into an infinite loop trying to output the error message.

Here's the session (captured using EMACS shell):

pberry@Dal:~/bridge_ghc_bug$ uname -a
Linux Dal 2.6.18-3-686 #1 SMP Mon Dec 4 16:41:14 UTC 2006 i686 GNU/Linux
pberry@Dal:~/bridge_ghc_bug$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
pberry@Dal:~/bridge_ghc_bug$ ghc -v --make main.hs
Glasgow Haskell Compiler, Version 6.6, for Haskell 98, compiled by GHC version 6.6
Using package config file: /usr/lib/ghc-6.6/package.conf
wired-in package base mapped to base-2.0
wired-in package rts mapped to rts-1.0
wired-in package haskell98 mapped to haskell98-1.0
wired-in package template-haskell mapped to template-haskell-2.0
Hsc static flags: -static
*** Chasing dependencies:
Chasing modules from: main.hs
Stable obj: []
Stable BCO: []
compile: input file main.hs
Created temporary directory: /tmp/ghc5182_0
*** Checking old interface for main:Main:
[1 of 1] Compiling Main             ( main.hs, main.o )
*** Parser:
*** Renamer/typechecker:

main.hs:30:12:
    No instance for (Show Rank)
      arising from use of `show' at main.hs:30:12-19
    Possible fix: add an instance declaration for (Show Rank)
    In the first argument of `(~?=)', namely `show Ten'
    In the expression: (show Ten) ~?= "T"
    In the second argument of `($)', namely
	`[(show Two) ~?= "2", (show Three) ~?= "3", (show Four) ~?= "4",
      (show Five) ~?= "5", (show Six) ~?= "6", (show Seven) ~?= "7",
  (show Eight) ~?= "8", (show Nine) ~?= "9", (show Ten) ~?= "T",

At this point ghc goes into an (apparently) infinite loop outputting spaces. When I interrupt it using Ctrl-C, it says:

*** Deleting temp files:
Deleting: /tmp/ghc5182_0/ghc5182_0.s
Warning: deleting non-existent /tmp/ghc5182_0/ghc5182_0.s
*** Deleting temp dirs:
Deleting: /tmp/ghc5182_0

Here's the file main.hs:

import System
import Test.HUnit
import Control.Monad
import Data.List

data Card = Card Rank Suit

data Suit = Clubs | Diamonds | Hearts | Spades
    deriving (Enum, Eq)

data Rank = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King | Ace
    deriving (Enum, Ord, Eq)

type Hand = [Card]

hand :: String -> Hand
hand = undefined

main = undefined

allTests = test $
           [show Two ~?= "2"
           ,show Three ~?= "3"
           ,show Four ~?= "4"
           ,show Five ~?= "5"
           ,show Six ~?= "6"
           ,show Seven ~?= "7"
           ,show Eight ~?= "8"
           ,show Nine ~?= "9"
           ,show Ten ~?= "T"
           ,hand "AK76543/32/AK2/3" ~?= exampleHand
           ]
    where exampleHand = []

Change History

Changed 6 years ago by thorkilnaur

  • os changed from Linux to Multiple
  • architecture changed from x86 to Multiple

Both of

Thorkil-Naurs-Computer:~/tn/test/GHC/trac/1176 thorkilnaur$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.6.20070220
Thorkil-Naurs-Computer:~/tn/test/GHC/trac/1176 thorkilnaur$ /Users/thorkilnaur/tn/install/ghc-HEAD-for-1066-20070211_1657/bin/ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.7.20070209
Thorkil-Naurs-Computer:~/tn/test/GHC/trac/1176 thorkilnaur$

repeat this performance on PPC Mac OS X 10.4. With

Thorkil-Naurs-Computer:~/tn/test/GHC/trac/1176 thorkilnaur$ /usr/local/bin/ghc --version               
The Glorious Glasgow Haskell Compilation System, version 6.4.1
Thorkil-Naurs-Computer:~/tn/test/GHC/trac/1176 thorkilnaur$

I cannot reproduce it, however.

Changed 6 years ago by simonpj

  • priority changed from normal to low
  • testcase set to tcfail177
  • milestone set to _|_

This is a bug in the pretty-printer. Here's a much smaller program that demonstrates the problem:

module Foo5 where

-- The more infix ops we have, the worse fsep works

allTests :: Bool
allTests :: Bool
allTests = foo
           [a ~?= b
           ,"Three" ~?= "3"
           ,"Four" ~?= "4"
           ,"Five" ~?= "5"
           ,"Five" ~?= "5"
           ,"Five" ~?= "5"
           ,"Two", "Two", "Two" 
           ,"Two", "Two", "Two" 
           ,"Two", "Two", "Two" 
           ,"Two", "Two", "Two" 
           ,"Two", "Two", "Two" 
           ,"Two", "Two", "Two"] 

a=""
b=""

(~?=) :: a -> a -> Bool
(~?=) = error "urk" 

foo :: a -> Int
foo x = 0

This gives the message:

Foo5.hs:15:12:
    Couldn't match expected type `Bool' against inferred type `[Char]'
    In the expression: "Two"
    In the first argument of `foo', namely
	`[a ~?= b, "Three" ~?= "3", "Four" ~?= "4", "Five" ~?= "5",
    "Five" ~?= "5", "Five" ~?= "5", "Two", "Two", "Two", "Two", "Two",
"Two", "Two", "Two", "Two", "Two", "Two", "Two", "Two", "Two",
"Two", "Two", "Two", "Two"]'
    In the expression:
	foo
	  [a ~?= b, "Three" ~?= "3", "Four" ~?= "4", "Five" ~?= "5",
     "Five" ~?= "5", "Five" ~?= "5", "Two", "Two", "Two", "Two", "Two",
 "Two", "Two", "Two", "Two", "Two", "Two", "Two", "Two", "Two",
 "Two", "Two", "Two", "Two"]

Notice the way that the layout is wrong: the lines are not indented enough. If you add one more line containing the infix operator, the infinite loop happens.

What is happening is that when the indent goes negative, the space generator goes wild.

I've fixed that that, so it'll put zero spaces in when the indent is negative.

But there's still a problem: the indent should not be going negative. The pretty-printing library could really do with someone looking at it carefully. We already have an open bug on that: #669, so I'm going to leave this one open because GHC's Pretty module isn't the same as the Text.PrettyPrint.HughesPJ module.

So infinite loop is fixed, but the bad formatting remains. I've added a test, tcfail177.

Please merge the fix the STABLE 6.6 branch:

Thu Mar  1 11:45:13 GMT 2007  simonpj@microsoft.com
  * Do not go into an infinite loop when pretty-printer 
             finds a negative indent (Trac #1176)

Changed 6 years ago by igloo

I've merged the fix, but I'm going to leave the bug open as the underlying problem isn't fixed.

Changed 6 years ago by thorkilnaur

  • owner set to thorkilnaur

Changed 6 years ago by thorkilnaur

The comments that I added to #669 imply that the problematic behaviour of GHC when printing these error messages could be caused by "an error in the use of the [pretty-printing] library" (quoting John Hughes). I will investigate further with that in mind.

Changed 5 years ago by thorkilnaur

Thanks to benedikt for taking up this matter (#2393). To clarify slightly, the present ticket is actually reported against the internal GHC version of the HughesPJ library. In the GHC source tree, the file is compiler/utils/Pretty.lhs. But the problem also exists for the HughesPJ library itself and is the problem reported as #1337. So the idea would be (as explained in #1337) to fix the matter in the HughesPJ library itself and then go back and fix it for the internal GHC version of the library as well. (I will refrain at this point from commenting on the fact that two versions of this library even exist. Ideally, the two versions of the library should be merged and GHC changed to use the external library.)

Best regards Thorkil

Changed 5 years ago by thorkilnaur

With

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.8.2

and the following variant of the Simon PJ test case

$ cat 1176PJ.hs 
module Foo5 where

-- The more infix ops we have, the worse fsep works

allTest1 :: Bool
allTest1 = foo
           ["One........" ~?= "1"
           ,"Two" ~?= "2"
           ,"Thre........." ~?= "3"
           ,"Four" ~?= "4"
           ,"Five" ~?= "5"
           ] 

allTest2 :: Bool
allTest2 = foo
           ["One........" ~?= "1"
           ,"Two.................." ~?= "2"
           ,"Thre........." ~?= "3"
           ,"Four" ~?= "4"
           ,"Five" ~?= "5"
           ] 

a=""
b=""

(~?=) :: a -> a -> Bool
(~?=) = error "urk" 

foo :: a -> Int
foo x = 0

I get

$ ghc --make 1176PJ.hs 
[1 of 1] Compiling Foo5             ( 1176PJ.hs, 1176PJ.o )

1176PJ.hs:6:11:
    Couldn't match expected type `Bool' against inferred type `Int'
    In the expression:
        foo
          ["One........" ~?= "1", "Two" ~?= "2", "Thre........." ~?= "3",
       "Four" ~?= "4", ....]
    In the definition of `allTest1':
        allTest1 = foo
                     ["One........" ~?= "1", "Two" ~?= "2", "Thre........." ~?= "3",
                ....]

1176PJ.hs:15:11:
    Couldn't match expected type `Bool' against inferred type `Int'
    In the expression:
        foo
          ["One........" ~?= "1", "Two.................." ~?= "2",
         "Thre........." ~?= "3", "Four" ~?= "4", ....]
    In the definition of `allTest2':
        allTest2 = foo
                     ["One........" ~?= "1", "Two.................." ~?= "2",
                    "Thre........." ~?= "3", ....]
$ 

The inconsistent indent of the second lines of the first list contained in these messages indicates that an error is, indeed, still present in the internal GHC version of the library.

Best regards Thorkil

Changed 5 years ago by igloo

OK, so I think this is fixed in the standalone pretty library (#2393).

As Thorkil says, GHC should really use this rather than having its own copy. I haven't compared the two libraries, but the only thing I can think of that would be standing in the way of that is that we need the library to understand GHC's FastStrings. I think that the missing piece of the puzzle is a utf8-bytestring library, which GHC could use itself (wrapping it in something to give it a uniq) and pretty would be able to accept (with its PStr constructor).

Changed 5 years ago by simonmar

  • architecture changed from Multiple to Unknown/Multiple

Changed 5 years ago by simonmar

  • os changed from Multiple to Unknown/Multiple

Changed 2 years ago by dterei

  • cc dterei added
  • failure set to None/Unknown

Changed 5 months ago by morabbin

Does GHC still use its own version of PP library? If not, close as fixed.

Note: See TracTickets for help on using tickets.