How to debug c/fortran on cheme server?¶
Page last updated on: 2019-10-14
Sample code¶
Sample code (Monte Carlo sampling) mc.f is used in this example.
Show source code mc.f
program baby_mc
c
c Monte Carlo for a trivial problem - 10 states with energy E(i)=i
c so p(i)=wxp(- beta * E(i)) / Z where Z=sum exp(- beta * E(i))
c
dimension n(10)
c
c warm up random number generator
c
idum=193728181
do i=1,1000
x=ran1(idum)
enddo
c
c input parameters
c
print*, 'enter beta and number of cycles'
read*, beta,ncycles
c
c initial state
c
i=1+10*ran1(idum)
c
e=0
n=0
do icycle=1,ncycles
j=1+10*ran1(idum) ! new state
if(j.lt.i) then
i=j ! accept if lower energy
else
z=ran1(idum) ! accept or not by metropolis test
if(z.lt.exp(-beta*(j-i))) i=j
endif
e=e+i
c
n(i)=n(i)+1
enddo
c
c output
c
print*, e/float(ncycles)
print '(10f8.5)', n/float(ncycles)
c
stop
end
c
1
FUNCTION ran1(idum)
INTEGER idum,IA,IM,IQ,IR,NTAB,NDIV
REAL ran1,AM,EPS,RNMX
PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836,
*NTAB=32,NDIV=1+(IM-1)/NTAB,EPS=1.2e-7,RNMX=1.-EPS)
INTEGER j,k,iv(NTAB),iy
SAVE iv,iy
DATA iv /NTAB*0/, iy /0/
if (idum.le.0.or.iy.eq.0) then
idum=max(-idum,1)
do 11 j=NTAB+8,1,-1
k=idum/IQ
idum=IA*(idum-k*IQ)-IR*k
if (idum.lt.0) idum=idum+IM
if (j.le.NTAB) iv(j)=idum
11 continue
iy=iv(1)
endif
k=idum/IQ
idum=IA*(idum-k*IQ)-IR*k
if (idum.lt.0) idum=idum+IM
j=1+iy/NDIV
iy=iv(j)
iv(j)=idum
ran1=min(AM*iy,RNMX)
return
END
First of all, you need to compile with "-g" option to make a debuggable code. Some common compiler flags are:
Flag | Example | Explanation |
---|---|---|
-g | gfortran -g mc.f | Turn on debug information |
-Wall | gfortran -Wall mc.f | Turn on all warning |
-O3 | gfortran -O3 mc.f | optimize code, but may disrupt debug info |
-o fname | gfortran -o mc mc.f | specify output file |
-c | gfortran -c mc.f | compile to object file only |
-l | ... | load library by name |
-L | ... | load library path |
-I | ... | load include path |
-static | gfortran -static mc.f | make static execytable |
-fdefault-integer-8 | use 8 byte long integer | |
-fdefault-real-8 | use 8 byte double float |
Some flags can be mixed and used together.
Compile using Makefile¶
If you are working on a programming project, the chance is you may need to to compile program again and again. Make tool comes handy in this situation.
Simply speaking, make tool reads a file and interpret three key elements: target, dependency and action.
For example, to make an executable mc from mc.f by running command gfortran -o mc mc.f
, we prepare a file named "Makefile":
mc: mc.f
gfortran -o mc mc.f
The white space in action line has to be a Tab.
Then, run
make
See what happens. What if you run make
again?
mc
is the target, and mc.f
is dependency. The first line means file mc
depends on file mc.f
. If mc.f
is newer than mc
, then the action line, which is also called recipe, will be triggered.
The target can be unconditional, and it is usefule to use this fueture to clean the directory.
mc: mc.f
gfortran -o mc mc.f
clean:
rm mc
When you run "make clean", it will trigger the rm mc
command.
With the above features, we can set up two ways of compiling a program, one for error checking and debugging, and one for optimization.
mc: mc.f
gfortran -o mc mc.f
clean:
rm mc
g:
gfortran -Wall -g -o mc mc.f
o:
gfortran -O3 -o mc mc.f
make g
to compile code for debug and make o
for optimize.
Command line debugger: gdb¶
Useful case: quick analysis of a core file.
Check if core dump is enabled:
ulimit -c
If it reports 0, set it to unlimited:
ulimit -c unlimited
Edit code to exceed array boundary, and run code to create a core dump.
Line 35:
n(i+100000)=n(i)+1
Create debuggable code:
make g
Run code:
./mc
It should crash and leave a core file.
Debug:
gdb mc core
bt
This will reveal where and why the error occurred.
Nemiver, GUI of gdb¶
Nemiver is a GUI front end of gdb.
Common operations:
- Load core file
- Load executable
- Set break point: click the space on right of line number or F8
- Run/continue to breakpoint: F5
- Run to current line: F11
- Step over: F6
- Step in: F7
- Stop a running session: F9
- Show variables