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.)
Related
I'm compiling my command-line program using dmd 2.072.1 on OS X El Capitan and trying to get line numbers to show in stack traces when debugging with LLDB. Currently the stack traces look like this:
core.exception.RangeError#Level.d(454): Range violation
----------------
4 Game 0x000000010b108ac1 _d_arraybounds + 97
5 Game 0x000000010b07f759 Level.__array + 41
6 Game 0x000000010b0969c4 void Level.Level.GenerateBlocks() + 992
7 Game 0x000000010b094c32 Level.Level Level.Level.__ctor(Renderer.Renderer, Level.Meshes, Level.Textures, bool, boo
Is it possible to see the line numbers with LLDB? If so, how? If not, what alternatives I have when using dmd? I'm developing my D programs with Emacs, but also have Xcode installed for other languages.
I'm on MacOS and had the same problem which I fixed. When I compiled all my C source files into object files I included the -g option. Then when compiling all the object files together to produce the final executable I included the -g option as well. Then lldb showed the proper line number where the error occurred!
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
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'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.
Looking for the lldb equivalent of the gdb "directory" command to add search paths for finding missing source code (or possibly similar functionality within xcode)?
Thanks in advance!
The target.source-map setting allows you define a series of a => b path remappings in the debug session. It's not identical to the gdb dir command, which is a list of directories to search for source files by base name, but you can solve the same problems with source-map. Here's an example where I move a source file to a hidden directory after compiling:
% cd /tmp
% echo 'int main () { }' > a.c
% clang -g a.c
% mkdir hide
% mv a.c hide/
% xcrun lldb a.out
(lldb) settings set target.source-map /tmp /tmp/hide
(lldb) l -f a.c
1 int main () { }
(lldb) br se -n main
Breakpoint created: 1: name = 'main', locations = 1
(lldb) r
Process 21674 launched: '/private/tmp/a.out' (x86_64)
Process 21674 stopped
* thread #1: tid = 0x1f03, 0x0000000100000f49 a.out`main + 9 at a.c:1, stop reason = breakpoint 1.1
#0: 0x0000000100000f49 a.out`main + 9 at a.c:1
-> 1 int main () { }
(lldb)
For more information about this setting, type set list target.source-map in lldb. fwiw you might have discovered this in lldb by doing apropos path which will list all commands/settings that have the word path in the name/description. Seeing that there was a setting by this name, you'd do settings list to see the list of settings and find out that it's filed under target..
The problem with lldb not being able to find your source files may be caused by flawed compilation process - i just spent several hours in attempt to find a lldb command to set path to sources by force but ended up discovering that i performed both actual compiling and linking with identical set of flags (-Wall -Werror -Wextra -g) in my Makefile... So compiler worked without warning and error messages despite errors (or warning treated as errors) actually existed. Fixing them fixed lldb workflow. Maybe developers should consider adding some warning (for newbies like me) in case program wasn't able to find sources (they were located in the very same directory in src folder).