How do you make a print statement with a line number and stack trace in Haskell?
You might like to play with GHC.Stack in the latest release of GHC.
Either use this...
Haskell Print Debugger - http://hackage.haskell.org/package/print-debugger
Or use this...
Debug.Trace.traceStack - https://hackage.haskell.org/package/base-4.8.2.0/docs/Debug-Trace.html
The former can print a single line formatted. The latter can print multiple lines unformatted.
Debug.Trace.traceStack requires compiling with -frof and -fprof-auto and running with +RTS -xc
Debug.Trace.traceStack Example (from "What I Wish I Knew When Learning Haskell"):
http://dev.stephendiehl.com/hask/):
$ ghc -O0 -rtsopts=all -prof -auto-all --make stacktrace.hs
./stacktrace +RTS -xc
Haskell Print Debugger Example:
-- http://i.imgur.com/av57mTS.png
import Debug.Print.StackTraceDebug
main = debugTraceIO "This has a stack trace."
____________________________________________
This has a stack trace. in thread "1" :
at Main.call(Main.hs:5)
If you just need to find your print statements the first option is a better choice.
p.s. I am advertising my own package located here:
https://github.com/JohnReedLOL/HaskellPrintDebugger
Related
Simple question. I am compiling an ada program with gnat. The gcc command ends up looking like gcc -c -Ia -Ibunch -Iof -Iincludes -I- -o /some/object/file.o /some/source/file.adb however the error format consists of just file.adb:line:offset: problem.
Is there any way to get GNAT make or gcc to print the full path to the file in its errors, as specified on the command line? IE: to get /some/source/file.adb:line:offset: problem.
I know that with the -gnatv one could argue that it prints the full path, but I want something significantly less verbose than that.
you need -gnatef option:
-gnatef
Display full source path name in brief error messages.
gcc -gnatef -c %CD%\file.adb
C:\DATA\jff\data\python\stackoverflow\file.adb:1:01: "procedure" expected
https://gcc.gnu.org/onlinedocs/gcc-4.3.6/gnat_ugn_unw/Switches-for-gcc.html
I develop OCaml programs in Emacs, compile and run the binary in the terminal.
It is possible to backtrace "failwith" error in Emacs like this post. But most of the time, "failwith" errors are raised when I execute a binary in the terminal. There is little information except
my error message
Fatal error: exception Failure("my error message")
Does anyone know if it is possible to backtrace that? I.e., understanding which .ml files are involved in such an execution?
If you compile with debugging support, you can ask for a backtrace with OCAMLRUNPARAM=b.
$ cat bt.ml
let g x = failwith "error"
let f x = g x
let main () = f 14
let () = main ()
$ ocamlopt -g -o bt bt.ml
$ OCAMLRUNPARAM=b bt
Fatal error: exception Failure("error")
Raised at file "pervasives.ml", line 30, characters 22-33
Called from file "bt.ml", line 7, characters 9-16
In small examples like this, the inliner will make the report a little less useful. In real world programs it's probably more useful.
(But it still might not be as detailed as you'd like.)
I'm looking to do something like this
$ stack eval 'functionDefinedInMain $ 1 + 1' > test1.txt
However, when I execute that, stderr tells me
<interactive>:1:1: Not in scope: ‘functionDefinedInMain’
I've also tried to pipe code into stack ghci, which gets me closer:
$ echo 'functionDefinedInMain $ 1+1' | stack ghci > test2.txt
Using main module: 1. Package `exp-proj' component exe:exp-proj with main-is file: /home/wizek/sandbox/exp-proj/exp-proj/src/Main.hs
Configuring GHCi with the following packages: exp-proj
$ cat test2.txt
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
[1 of 5] Compiling Utils ( /home/wizek/sandbox/exp-proj/exp-proj/src/Utils.hs, interpreted )
[2 of 5] Compiling Vertex ( /home/wizek/sandbox/exp-proj/exp-proj/src/Vertex.hs, interpreted )
[3 of 5] Compiling Edge ( /home/wizek/sandbox/exp-proj/exp-proj/src/Edge.hs, interpreted )
[4 of 5] Compiling Lib ( /home/wizek/sandbox/exp-proj/exp-proj/src/Lib.hs, interpreted )
[5 of 5] Compiling Main ( /home/wizek/sandbox/exp-proj/exp-proj/src/Main.hs, interpreted )
Ok, modules loaded: Utils, Vertex, Edge, Lib, Main.
*Main Edge Lib Utils Vertex> 3
*Main Edge Lib Utils Vertex> Leaving GHCi.
As you can see, the output (which is just the number 3 in this example) file is polluted by GHCi.
I'd like the content of the file to be instead:
$ cat test2.txt
3
How can I either
load all my project modules with stack eval as specified in my .cabal file to execute code in context, or
suppress GHCi output to stdout? (I don't mind if GHCi puts messages on stderr)
$ stack --version
Version 1.0.2, Git revision fa09a980d8bb3df88b2a9193cd9bf84cc6c419b3 (3084 commits) x86_64
edit: Added unix and bash tags since it might be possible to achieve this by piping together different stack/GHCi commands even without explicit support from stack.
The -e flag in ghc -e expects a Haskell expression and has—by default—only access on Prelude. You need to use additional functions fully qualified:
stack eval 'Library.someFunc $ 1+1'
^^^^^^^^
However, this does only work in the following circumstances:
The module must be part of your library, not your executable.
The expression must be exported from the module.
If you're just trying to use Main.xxx, make sure that Main is a visible module in your library. This also concludes that you cannot use eval for executable only projects. However, this can lead to strange problems. For example, GHCi will try to import Main twice, once via the executable and once via the library.
Example
$ stack new exp-eval simple
$ cd exp-eval
$ cat addition >> exp-eval.cabal
$ stack eval 'Main.main'
Where addition has the following content:
library
hs-source-dirs: src
exposed-modules: Main
default-language: Haskell2010
build-depends: base >= 4.7 && < 5
I don't quite get what you want to do - do you want to execute the main - then use
$> stack runghc ./src/Main.hs > test.txt
or
$> stack build
$> stack exec -- modulename > test.txt
to invoke the compiled binary.
If you have a function that is exported in main it is easiest to use stack ghci and call the function from inside - if it produces a String you can then use
writeFile "test.txt" (myfunction parameter1 parameter2)
to get the desired result.
I have not used stack eval before but I guess you have to export your function in a library for that, I guess your cabal file says that you have only an export of an executable - to give you more info I would need your cabal file.
If we get a <<loop>>, it means that Haskell had managed to detect an infinite loop. Is there a way to get ghc to tell us where this loop happened? It seems that Haskell should have this information somewhere.
Compile your app with -prof and -fprof-auto(if you're using Cabal, use --enable-executable-profiling and --ghc-options=-fprof-auto) and then run it with +RTS -xc. It'll print a stack trace when errors happen. This should help you narrow your scope.
Example:
➜ haskell cat loop.hs
myFun :: Int
myFun =
let g = g + 1
in g + 10
main = print myFun
➜ haskell ghc loop.hs -prof -fprof-auto
[1 of 1] Compiling Main ( loop.hs, loop.o )
Linking loop ...
➜ haskell ./loop +RTS -xc
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace:
Main.myFun.g,
called from Main.myFun,
called from Main.CAF
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace:
Main.myFun.g,
called from Main.myFun,
called from Main.CAF
loop: <<loop>>
In addition to what has already been written: These loops are only detected at run-time. The detection is based on the code attempting to evaluate a value which is already being evaluated [by the same thread]. Clearly that should never happen.
If you're looking for a compiler switch to detect this at compile-time... you're out of luck. It's easy enough to statically spot recursion, but deciding whether the recursion is infinite or not isn't so easy.
I am interested in seeing the code where gcc has actually optimized the code. Is there a way I could do?
I have gone through few other similar questoins, I have tried following few things,
-Wa,ahl=filename.lst :- this option is really good, you can browse the code and corresponding machine code, but it is not good when I enable O3 option.
Dumping optimized tree :- I am sure gcc is giving me good amount of debug information. But I do not how to decipher it. I will be glad if someone could point to any available information.
Is there any other better way, to find out what part of the code gcc optimized?
Thanks,
Madhur
You can compile the code twice, first with:
$ gcc -O0 -S -o yourfile_o0.s
Then with:
$ gcc -O3 -S -o yourfile_o3.s
Then you can diff the two resulting assembly files:
$ diff -u yourfile_o0.s yourfile_o3.s
$ vim -d yourfile_o0.s yourfile_o3.s
$ emacs --eval '(ediff "yourfile_o0.s" "yourfile_o3.s")'
Look at the assember code or decompile your compiled application. C decompilers produce ugly C code, but for analyzing which code was generated, it have to suffice.