so I have found the culprit, by defining this function:
Import Debug.Trace
headMarker :: String -> [a] -> a
headMarker marker [] = trace marker (head [])
headMarker _ array = head array
and replacing calls to head to "headMarker "XX"", "headmarker "YY"" and so on.
it works but I would really rather have a compiler/runtime based solution which would not force me to modify my code to track the bug (and would be simpler to use in case the problem comes from a library).
If anybody has an idea what I did wrong with the -xc and the -RTS I'm all ears... I'd love to test it and find out how to make that work reliably.
Emmanuel
you mean in combination with the RTS/profiling trick?
If I must do something like that, I'll just mark my code with debug lines or code the else situations (like making a headMarker with an extra parameter "String marker" and it will output the marker on stdoud if the array is empty), seems less work...
I was really hoping being able to fix it without having the modify the code, it's disappointing, I think.On Tue, Nov 6, 2012 at 9:47 PM, Christian Maeder <Christian.Maeder@dfki.de> wrote:
Usually, these head calls are in your code. Do "fgrep head" on your sources and replace all suspicious occurrences. Use "let h : _ = l in ..." and "h" instead of "head l" for proper positions.
HTH Christian
Am 06.11.2012 12:44, schrieb Emmanuel Touzery:
Hello,
I'm getting really frustrated by error handling in haskell. By this
I mean "assert"-like errors. Which means, something that should never
happen, happens. This will happen in the development and deployment of
software of any size.
When coding the feature you'll say, I don't need to handle the
"Nothing" case, because it will never happen, or almost never, and this
is not critical production software.
But if one day it happens you find yourself with a several thousand
lines program and all you have to debug is the input data (most of the
time anyway, sometimes not even that) and this error message (for
instance):
*** Exception: Prelude.head: empty list
And you don't know even, did you call "head" or maybe a library you
are using called it.
This is really poor compared to what Java, python and others
offers. I can understand that it's difficult to provide a stack trace,
especially with lazy evaluation, but at least the function name and
maybe a line number... Actually I don't know why it would be so
difficult to also give me the values of the parameters of the
function... using print and if it's a pure function it intuitively
doesn't seem difficult.
I've tried ghci with :trace and ":set -fbreak-on-exception" and I
got nowhere. It breaks in things which are not important (I have no idea
where it breaks, it claims an exception was thrown, maybe but not in my
code and it never reaches my code for sure). After hitting ":continue"
many times, I get to my exception and there I didn't manage to get
useful information (:hist never printed me anything).
But I would like not to have to use ghci at all. And to avoid
having to write all over the place in my code these "else" and case
situations for things I assume are impossible (these are cases I would
not write in other modern languages).
This is a feature for which I would be ready to pay a 50% speed
penalty and 50% memory use penalty.
I understand if it's the haskell way of writing all those else
clauses... But I think in that case it really makes it compare
negatively to other languages. It would be a real minus in my opinion
(including to code readability).
I have read (quickly) those but didn't find the solution there:
http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/ghci-debugger.html
http://book.realworldhaskell.org/read/error-handling.html
Any advice will be welcome! I really hope I missed something.
Emmanuel