
Hi,
I tried the bang patterns, it seems to force evaluation enough in most
cases to triger the "trace" call.
Thanks a lot,
Patrick
On Sun, Aug 8, 2010 at 2:18 PM, Daniel Fischer
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 ()
Unneeded
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
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada