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.
Related
Consider the following trivial Fortran program that adds two integers via a subroutine and prints the result:
PROGRAM MAIN
INTEGER I, J, SUM
I = 1
J = 1
CALL ADD(I, J, SUM)
WRITE(*,*) SUM
END
SUBROUTINE ADD(I, J, SUM)
INTEGER I, J, SUM
SUM = I + J
END
Compiling via gfortran -g -O0 gdb-mwe.f -o gdb-mwe and running in the GNU Debugger, I want to call ADD from the debugger with modified input arguments right before the write output. Here's what happens:
Reading symbols from gdb-mwe...done.
(gdb) break 10
Breakpoint 1 at 0x4007dd: file gdb-mwe.f, line 10.
(gdb) r
Starting program: /home/username/Documents/Fortran/gdb-mwe
Breakpoint 1, MAIN__ () at gdb-mwe.f:10
10 WRITE(*,*) SUM
(gdb) p j = j+1
$2 = 2
(gdb) call add(i,j,sum)
Program received signal SIGSEGV, Segmentation fault.
0x000000000040079a in add (
i=<error reading variable: Cannot access memory at address 0x1>,
j=<error reading variable: Cannot access memory at address 0x2>,
sum=<error reading variable: Cannot access memory at address 0x2>)
at gdb-mwe.f:18
18 SUM = I + J
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(add) will be abandoned.
When the function is done executing, GDB will silently stop.
How do I get this right?
As pointed out in the comments, the open bugs in gdb prevents doing this currently.
A possible workaround would be to debug a 32-bit version of the code. This results in some differences, but for simple debugging tasks it may be sufficient.
For intel fortran compilers, this requires only adding the -m32 flag (provided 32-bit libraries have been installed).
For gfortran it seems that installing the multilib package first is necessary, as show in this questions.
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.)
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
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.
I've been sitting here for a while quite baffled as to why my debugger keeps displaying an error in my code when the program runs fine. There are three parts to a very simple program that is just reading in information from a file.
My code is broken into three Fortran files given below and compiled via
ifort -o test global.f90 read.f90 test.f90
global.f90:
module global
implicit none
integer(4), parameter :: jsz = 904
end module global
read.f90:
subroutine read(kp,q,wt,swt)
implicit none
integer(4) :: i, j
integer(4), intent(in) :: kp
real(8), intent(out) :: swt, q(kp,3), wt(kp)
swt = 0.0d0; q(:,:) = 0.0d0; wt(:) = 0.0d0
open(7,file='test.dat')
read(7,*) ! Skipping a line
do i = 1, kp
read(7,1000)(q(i,j),j=1,3), wt(i)
swt = swt + wt(i)
end do
close(7)
return
1000 format(3F10.6,1X,1F10.6)
end subroutine read
test.f90:
program test
use global
integer(4) :: i, j
real(8) :: tot, qq(jsz,3), wts(jsz)
call read(jsz,qq,wts,tot)
stop
end program test
The error I keep receiving is
Breakpoint 1, read (kp=904,
q=<error reading variable: Cannot access memory at address 0x69bb80>,
wt=..., swt=6.9531436082559572e-310) at read.f90:6
This error appears right when the subroutine of read is called. In other words, I'm adding a breakpoint at the read subroutine and running the code in gdb after the breakpoint is added. The program will continue to run as expected and give the correct outputs when I include write statements in the 'test' program. However, if I use the gdb print options I receive an error of 'Cannot access memory at address 0x69bb80' for array q only. All other arrays and variables can be displayed with no problems.
As I would like the read subroutine to be a stand alone subroutine and not necessarily use any global parameters, I have not used the global module and instead called the variable kp into the subroutine. I decided to test whether using the global module would help, and if I use jsz in place of kp, I do indeed remove the error. However, since this isn't my overall goal with the subroutine, I would hopefully like to figure out how to fix this without the use of the global module. (I also tried not using the global at all and setting the parameter variable of kp in the test.f90 program directly, but this also gives the error.)
Any insight on possible reasons for this error, or suggestions to try and fix the memory addressing issue would be greatly appreciated.
I think this is an issue specific to the ifort+gdb combination that is fixed with newer gdb versions. Here's a smaller example to reproduce the issue:
$ cat test.f90
subroutine bar(arg)
integer, intent(inout):: arg
print *, 'bar argument is', arg
arg = 42
end subroutine bar
program test
integer:: param
param = 3
call bar(param)
print *, 'post-bar param:', param
end program test
$ ifort -g -O0 -o test test.f90
$ gdb --quiet test
Reading symbols from /home/nrath/tmp/test...done.
(gdb) b 4
Breakpoint 1 at 0x402bd0: file test.f90, line 4.
(gdb) r
Starting program: /home/nrath/tmp/test
[Thread debugging using libthread_db enabled]
Breakpoint 1, bar (arg=#0x2aaa00000003) at test.f90:4
4 print *, 'bar argument is', arg
(gdb) p arg
$1 = (REF TO -> ( INTEGER(4) )) #0x2aaa00000003: <error reading variable>
(gdb) quit
$ gdb --version | head -1
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
However, if you compile with gfortran instead of ifort, or if you use GDB 7.7.1, it works fine.
Did you add the INTERFACE statement to the end of your programme?
You need it when you call a function that is not contained in the programme.