I've compiled a Fortran code, which contains several modules, using both gfortran 4.4 and intel 11.1 and subsequently tried to debug it using both gdb and DDT. In all cases, I cannot see the values of any variables that are declared in modules. These global variables have values, as the code still runs correctly, but I can't see what the values are in my debuggers. Local variables are fine. I've had trouble finding a solution to this problem elsewhere online, so perhaps there is no straightforward solution, but it's going to be really difficult to debug my code if I can't see the values of any of my global variables.
With newer GDBs (7.2 if I recall correctly), debugging modules is simple. Take the following program:
module modname
integer :: var1 = 1 , var2 = 2
end module modname
use modname, only: newvar => var2
newvar = 7
end
You can now run:
$ gfortran -g -o mytest test.f90; gdb --quiet ./mytest
Reading symbols from /dev/shm/mytest...done.
(gdb) b 6
Breakpoint 1 at 0x4006a0: file test.f90, line 6.
(gdb) run
Starting program: /dev/shm/mytest
Breakpoint 1, MAIN__ () at test.f90:6
6 newvar = 7
(gdb) p newvar
$1 = 2
(gdb) p var1
No symbol "var1" in current context.
(gdb) p modname::var1
$2 = 1
(gdb) p modname::var2
$3 = 2
(gdb) n
7 end
(gdb) p modname::var2
$4 = 7
(gdb)
In gdb, try referencing the global variables with names like __modulename__variablename
You can check that this is the right mangling scheme using nm and grep to find one of your global variables in the symbols of your program.
If that doesn't work, make sure you're using a recent version of gdb.
Here's a thread on this issue: http://gcc.gnu.org/ml/fortran/2005-04/msg00064.html
I had the same issue (GNU gdb 7.9 running in parallel with MPI). What worked for me was the following:
p __modname_mod_var
That is: double underscore, the name of the module, underscore, mod, the name of the variable.
Compiling with -gstabs+ instead of -g may also fix some issues (but not the present one).
Related
I asked a question about some strange behavior from a Fortran compiler here:
gfortran compiler cannot find misspelled full directory
Basically, the compiler sporadically** complains that a file is missing, but the problem is that the printed name of the file (full path, actually) is misspelled, so no wonder it's "missing". I thought that I resolved the problem by using relative paths, but it turns out that the problem was just dormant. Here's an example of one such complaint:
C:\Users\charl\Documents\GitHub\MOONS>gfortran -fopenmp -g -fimplicit-none -cpp
C:/Users/charl/Documents/GitHub/MOONS/code/globals/current_precision.f90
...
C:/Users/charl/Documents/GitHub/MOONS/code/solvers/induction/init_Bfield.f90
C:/Users/charl/Documents/GitHub
gfortran: error:
C:/Users/charl/Documents/GitHubMOONS/code/solvers/induction/init_Sigma.f90: No such file or directory
Notice that the forward slash ('/') is missing between GitHub and MOONS, and instead reads "GitHubMOONS". This path was correctly written in the makefile.
** I say sporadically because changing lines in the code sometimes results in the error disappearing. Similarly, removing some unused modules (that compile just fine) from my compilation list results in the error disappearing.
The compiler I'm using is:
GNU Fortran (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 4.9.2 Copyright (C) 2014 Free Software Foundation, Inc.
But I've seen the same problem with more recent compilers, e.g.:
x86_64-7.1.0-release-posix-seh-rt_v5-rev2
I think I am seeing a trend with when this error occurs, and it seems to occur more frequently when modules pass on public interfaces to other modules.
Question
So, my question is, given the following two modules:
module add_int_mod
implicit none
private
public :: add
interface add; module procedure add_int; end interface
contains
subroutine add_int(a,b)
implicit none
integer,intent(inout) :: a
integer,intent(in) :: b
a = a + b
end subroutine
end module
module add_all_mod
use add_int_mod
implicit none
private
public :: add
end module
What is the difference between these two programs, if any?
Program 1
program main
use add_all_mod ! only difference
implicit none
integer :: a,b
a = 0
b = 1
call add(a,b)
write(*,*) 'a = ',a
write(*,*) 'b = ',b
end program
Program 2
program main
use add_int_mod ! only difference
implicit none
integer :: a,b
a = 0
b = 1
call add(a,b)
write(*,*) 'a = ',a
write(*,*) 'b = ',b
end program
I appreciate any help/suggestions.
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'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.
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).