[Haskell-beginners] Using Debug.Trace

Daniel Fischer daniel.is.fischer at web.de
Sun Aug 8 14:18:55 EDT 2010

On Sunday 08 August 2010 19:14:41, Patrick LeBoutillier wrote:
> Hi all,
> I'm writing a parser for a binary format, and I'm trying to debug it
> since I have a bug and the code is getting lost in the bits and bytes.
> Basically my main is like this:
>   import Data.Binary.Get
>   import Debug.Trace
>   import qualified Data.ByteString.Lazy as L
>   main = do
>     bytes <- L.readFile "song.gp4"
>     let (version, bytes') = getVersion bytes
>     putStrLn version
>     let stuff = runGet (getDocument version) bytes'
>     putStrLn $ show stuff

putStrLn $ show stuff === print stuff

>     return ()


> The getVersion and getDocument functions use the Data.Binary.Get monad
> to decode the byte string into various objects.
> I tried sprinkling "trace" calls a bit everywhere and I realize they
> don't always get called at the expected time.

trace prints its first argument when the second is demanded, so to print 
earlier, you can in general add more strictness to your programme, but I'm 
not sure if that makes a difference for Get, since that has no freedom to 
reorder the sequence in which the values are read. So with traces in the 
right places, you should get tracing output while the deserialisation is 
underway automatically.
Whether in

getSomeObject = do
    foo <- get
    !bar <- trace ("foo is " ++ show foo) get
    let !baz = trace ("bar is " ++ show bar) $ fiddle foo bar
    return $! trace ("baz is " ++ show baz) (wibble baz foo bar)

the bangs make a difference regarding trace output, I don't know.

> Most of them are only
> called when I reach the "putStrLn $ show stuff" statement.
> Unfortunately that doesn't help me because I get a
>   *** Exception: too few bytes. Failed reading at byte position 35939
> before that.

That usually means the file hasn't the correct format, e.g. some size 
(length of list) has been written in little-endian order and is read in 
big-endian, so get tries to read more items than there are.

> Is this happening because I'm using lazy IO to read the file?

Unlikely. What is the file size on disk? If it's larger than 35939 bytes, 
you have an IO problem, but still Data.ByteString.Lazy.readFile wouldn't be 
the first on my list of suspects.

> Is there a way to force the evaluation of these "trace" calls?

Seeing more of the code could help coming up with ideas.

> Are there any other ways to debug this kind of stuff in Haskell?

Break things down into smaller pieces and test those.
And there's the ghci-debugger, I hear if one has learned to use it, it's 
quite helpful.

> Thanks a lot,
> Patrick

More information about the Beginners mailing list