[Haskell-beginners] Using Debug.Trace
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
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
> Thanks a lot,
More information about the Beginners