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