Segmentation Fault on Linux, but not on Windows

In summary, the conversation is about running a program on two different operating systems (Ubuntu and Windows) and receiving a segmentation fault warning on Ubuntu but not on Windows. The program was compiled with gfortran on both systems and the conversation also discusses various steps and inputs involved in the program's execution, such as time steps, force calculations, and torque calculations."
  • #1
LucasCampos
17
0
When I run a program on Ubuntu (10.04 x64) I receive a warning of segmentation fault. But when on windows (seven, x64), I do not receive this error. This program was compiled with gfortran on both systems. Any ideas why?

Code:
Program Lennard
Implicit None 
Double Precision sigma,e,dt,fx,fy,xi,yi,axi,ayi,fxmid,fymid,xmidi,&
ymidi,axmidi,aymidi,teti,omegi,tori,ineri,radi,massi,xj,yj,axj,&
ayj,xmidj,ymidj,axmidj,aymidj,tetj,omegj,torj,&
inerj,radj,massj,vxi,vyi,vxmidi,vymidi,vxj,vyj,vxmidj,vymidj,alfi,alfj,t
Integer counter,nshow
Call Opener
Call Inserter_General (dt,sigma,e)
Call Inserter_i (massi,radi,vyi,vxi,yi,xi,omegi,teti)
Call Inserter_j (massj,radj,vyj,vxj,yj,xj,omegj,tetj)
counter=0
ineri=0.5D0*massi*radi**2
inerj=0.5D0*massj*radj**2
Call Euler (sigma,e,dt,fx,fy,xi,yi,axi,ayi,fxmid,fymid,xmidi,&
ymidi,axmidi,aymidi,teti,omegi,tori,ineri,radi,massi,xj,yj,axj,&
ayj,xmidj,ymidj,axmidj,aymidj,tetj,omegj,torj,&
inerj,radj,massj,vxi,vyi,vxmidi,vymidi,vxj,vyj,vxmidj,vymidj,alfi,alfj,&
t)
End

Subroutine Inserter_General (dt,sigma,e)
Implicit None
Double Precision dt,sigma,e
Integer nshow
Write (*,*) 'Insert time step'
Read (*,*) dt
Write (*,*) 'Insert sigma'
Read (*,*) sigma
Write (*,*) 'Insert épislon'
Read (*,*) e
Write (*,*) 'Insert steps between output'
Read (*,*) nshow
End

Subroutine Inserter_i (massi,radi,vyi,vxi,yi,xi,omegi,teti)
Implicit None
Double Precision massi,radi,vyi,vxi,yi,xi,omegi,teti
Write (*,*) "Insert first disk's mass" 
Read (*,*) massi
Write (*,*) "Insert first disk's radius"
Read (*,*) radi
Write (*,*) "Insert first disk's inicial vertical speed"
Read (*,*) vyi
Write (*,*) "Insert first disk's inicial horizontal speed"
Read (*,*) vxi
Write (*,*) "Insert first disk's initial vertical position"
Read (*,*) yi
Write (*,*) "Insert first disk's initial horizontal position"
Read (*,*) xi
Write (*,*) "Insert first disk's initial angular speed"
Read (*,*) omegi
Write (*,*) "Insert first disk's initial angular position" 
Read (*,*) teti
End

Subroutine Inserter_j (massj,radj,vyj,vxj,yj,xj,omegj,tetj)
Implicit None
Double Precision massj,radj,vyj,vxj,yj,xj,omegj,tetj
Write (*,*) "Insert second disk's mass" 
Read (*,*) massj
Write (*,*) "Insert second disk's radius"
Read (*,*) radj
Write (*,*) "Insert second disk's inicial vertical speed"
Read (*,*) vyj
Write (*,*) "Insert second disk's inicial horizontal speed"
Read (*,*) vxj
Write (*,*) "Insert second disk's initial vertical position"
Read (*,*) yj
Write (*,*) "Insert second disk's initial horizontal position"
Read (*,*) xj
Write (*,*) "Insert second disk's initial angular speed"
Read (*,*) omegj
Write (*,*) "Insert second disk's initial angular position" 
Read (*,*) tetj
End

Subroutine Force (fx,fy,xi,yi,axi,ayi,fxmid,fymid,xmidi,ymidi,axmidi,&
aymidi,radi,massi,xj,yj,axj,ayj,xmidj,ymidj,axmidj,aymidj,radj,massj,&
vxi,vyi,vxmidi,vymidi,vxj,vyj,vxmidj,vymidj,e,sigma,dt)
Implicit None
Double Precision fx,fy,xi,yi,axi,ayi,fxmid,fymid,xmidi,ymidi,axmidi,&
aymidi,radi,massi,xj,yj,axj,ayj,xmidj,ymidj,axmidj,aymidj,radj,massj,&
vxi,vyi,vxmidi,vymidi,vxj,vyj,vxmidj,vymidj,e,sigma,dt
fx=4*e*(12*((sigma**12)/(abs(xi-xj)**13))-(6*(sigma**6)/(abs(xi-xj)**7)))
fy=4*e*(((sigma**12)/(abs(yi-yj)**13))-((sigma**6)/(abs(yi-yj)**7)))
IF(xj .GT. xj) axi=fx/massi
IF(xj .GT. xj) axj=-fx/massj
IF(yj .GT. yj) ayi=fy/massi
IF(yj .GT. yj) ayj=-fy/massj
IF(xj .LE. xj) axi=-fx/massi
IF(xj .LE. xj) axj=fx/massj
IF(yj .LE. yj) ayi=-fy/massi
IF(yj .LE. yj) ayj=fy/massj
vxmidi=vxi+axi*(dt/2)
xmidi=xi+vxi*(dt/2)
vymidi=vyi+ayi*(dt/2)
ymidi=yi+vyi*(dt/2)
vxmidj=vxj+axj*(dt/2)
xmidj=xj+vxj*(dt/2)
vymidj=vyj+ayj*(dt/2)
ymidj=yj+vyj*(dt/2)
fxmid=4*e*(((sigma**12)/(abs(xmidi-xmidj)**13))-((sigma**6)/&
(abs(xmidi-xmidj)**7)))
fymid=4*e*(((sigma**12)/(abs(ymidi-ymidj)**13))-((sigma**6)/&
(abs(ymidi-ymidj)**7)))
!
IF(xmidj .GT. xmidj) axmidi=fxmid/massi
IF(xmidj .GT. xmidj) axmidj=-fxmid/massj
IF(ymidj .GT. ymidj) aymidi=fymid/massi
IF(ymidj .GT. ymidj) aymidj=-fymid/massj
!
IF(xmidj .LE. xmidj) axmidi=-fxmid/massi
IF(xmidj .LE. xmidj) axmidj=fxmid/massj
IF(ymidj .LE. ymidj) aymidi=-fymid/massi
IF(ymidj .LE. ymidj) aymidj=fymid/massj
!
End

Subroutine EulerTransI (vxi,xi,vyi,yi,axmidi,vxmidi,aymidi,vymidi,dt) 
Implicit None
Double Precision vxi,xi,vyi,yi,axmidi,vxmidi,aymidi,vymidi,dt
vxi=vxi+axmidi*dt
xi=xi+vxmidi*dt
vyi=vyi+aymidi*dt
yi=yi+vymidi*dt
End

Subroutine EulerTransJ (vxj,xj,vyj,yj,axmidj,vxmidj,aymidj,vymidj,dt)
Implicit None
Double Precision vxj,xj,vyj,yj,axmidj,vxmidj,aymidj,vymidj,dt
vxj=vxj+axmidj*dt
xj=xj+vxmidj*dt
vyj=vyj+aymidj*dt
yj=yj+vymidj*dt
End

Subroutine Torque (xmidi,xmidj,ymidi,ymidj,fxmid,fymid,tori,torj,teti,&
tetj,radi,radj,ineri,inerj,alfi,alfj)
Implicit None
Double Precision xmidi,xmidj,ymidi,ymidj,fxmid,fymid,tori,torj,teti,&
tetj,radi,radj,ineri,inerj,alfi,alfj
IF(xmidj .LE. xmidj) fxmid=-fxmid
IF(ymidj .LE. ymidj) fymid=-fymid
!
tori=radi*((fymid*cos(teti))-(fxmid*sin(teti)))
torj=-radj*((fymid*cos(tetj))-(fxmid*sin(tetj)))
alfi=tori/ineri
alfj=torj/inerj
End

Subroutine EulerRotI (omegi,alfi,teti,dt)
Implicit None 
Double Precision omegi,alfi,teti,dt
omegi=omegi+alfi*dt
teti=teti+omegi*dt
End

Subroutine EulerRotJ (omegj,alfj,tetj,dt)
Implicit None 
Double Precision omegj,alfj,tetj,dt
omegj=omegj+alfj*dt
tetj=tetj+omegj*dt
End

Subroutine Euler (sigma,e,dt,fx,fy,xi,yi,axi,ayi,fxmid,fymid,xmidi,&
ymidi,axmidi,aymidi,teti,omegi,tori,ineri,radi,massi,xj,yj,axj,&
ayj,xmidj,ymidj,axmidj,aymidj,tetj,omegj,torj,&
inerj,radj,massj,vxi,vyi,vxmidi,vymidi,vxj,vyj,vxmidj,vymidj,alfi,alfj,&
t)
Implicit None 
Double Precision sigma,e,dt,fx,fy,xi,yi,axi,ayi,fxmid,fymid,xmidi,&
ymidi,axmidi,aymidi,teti,omegi,tori,ineri,radi,massi,xj,yj,axj,&
ayj,xmidj,ymidj,axmidj,aymidj,tetj,omegj,torj,&
inerj,radj,massj,vxi,vyi,vxmidi,vymidi,vxj,vyj,vxmidj,vymidj,alfi,alfj,t
Integer counter,nshow
!
100 Call Force (fx,fy,xi,yi,axi,ayi,fxmid,fymid,xmidi,ymidi,axmidi,&
aymidi,radi,massi,xj,yj,axj,ayj,xmidj,ymidj,axmidj,aymidj,radj,massj,&
vxi,vyi,vxmidi,vymidi,vxj,vyj,vxmidj,vymidj,e,sigma,dt)
Call EulerTransI (vxi,xi,vyi,yi,axmidi,vxmidi,aymidi,vymidi,dt)
Call EulerTransJ (vxj,xj,vyj,yj,axmidj,vxmidj,aymidj,vymidj,dt)
Call Torque (xmidi,xmidj,ymidi,ymidj,fxmid,fymid,tori,torj,teti,&
tetj,radi,radj,ineri,inerj,alfi,alfj) 
Call EulerRotI (omegi,alfi,teti,dt)
Call EulerRotJ (omegj,alfj,tetj,dt)
t=t+dt
counter=counter+1
Write (1,*) xi+cos(teti)*radi,yi+sin(teti)*radi
Write (2,*) xj+cos(tetj)*radj,yj+sin(tetj)*radj
If (mod(nshow,counter) .EQ. 0.0D0) Call Table (xi,yi,xj,yj)
Write (3,*) vxj,vyj,yj,xj
Write (3,*) axmidj,aymidj,axmidi,aymidi
If (t .GT. 900) Go to 200
Go to 100
200 Write (*,*) 'Done'
End

Subroutine Opener
Open (Unit=1,File="movi.dat")
Open (Unit=2,File="movj.dat")
Open (Unit=3,File="cmi.dat")
Open (Unit=4,File="cmj.dat")
End

Subroutine Table (xi,yi,xj,yj,teti,tetj,radi,radj)
Implicit None
Double Precision xi,yi,xj,yj,teti,tetj,radi,radj
Write (1,*) xi+cos(teti)*radi,yi+sin(teti)*radi
Write (2,*) xj+cos(tetj)*radj,yj+sin(tetj)*radj
Write (3,*) xi,yi
Write (4,*) xj,yj
End
 
Technology news on Phys.org
  • #2
I've found the problem. It was on the Call Table. Not all variables used was declared. Just a small change and it all worked out.
 
  • #3
This problem illustrates that it is a good idea to test your program on as many different machines and as many different compilers as you can get your hands on. Sometimes a program will work on a Windows machine but not on a Linux machine, sometimes the other way around as is the case here. Sometimes it will only work on a Mac, or only on a Sun. Sometimes your program won't even compile on other machines because you just happen to have used a non-standard library function. Unless you read the documentation carefully, it is not at all clear that the function in question is non-standard; ofttimes vendors won't even say that their spiffy little function is non-standard.
 
  • #4
Indeed, it is a great idea. In this case, windows' version should not have worked. If I hadn't the linux problem, I would have never noticed my mistake. I'm not using libraries yet. But I guess it would that idea even better.
 
  • #5
I'm curious as to how under the Windows system you were able to compile using undeclared variables by issuing IMPLICIT NONE. Oh well, as D H mentioned, I guess it's always better to try it on a few different platforms.
 
  • #6
I could compile on both, Windows and Linux. I think gfortran didn't return errors because they are declared on the subroutine, but are not called. That's why the segfault. The subroutine was trying to access variables which it was not entitled to.
 
  • #7
LucasCampos said:
The subroutine was trying to access variables which it was not entitled to.

Ah, are you familiar with the INTENT property of subroutine variables? e.g.
Code:
...
SUBROUTINE func_exp(x,n,y)
IMPLICIT NONE
REAL(kind=r_def),INTENT(IN) :: x !--incoming number, not allowed to be changed
INTEGER(kind=i_def),INTENT(IN) :: n !--ditto
REAL(kind=r_def),INTENT(OUT) :: y !--result of the subroutine

y = x**n

END SUBROUTINE

It's something I do for each subroutine. In times such as yours, you may get a nice pretty compiler error saying a variable has incorrect intent rather than the bane of us all...the seg fault.

p.s. There is also an INTENT(INOUT) which allows an incoming variable to be changed.
 
  • #8
LucasCampos said:
I'm not using libraries yet.
Whether you know it or not, you most certainly are. Those calls to read, write, sin, cos -- those are library functions. You didn't write those functions, did you? Those functions reside in a library -- in this case they are a part of the library provided au gratis by the language.
 
  • #9
minger said:
Ah, are you familiar with the INTENT property of subroutine variables? e.g.
Code:
...
SUBROUTINE func_exp(x,n,y)
IMPLICIT NONE
REAL(kind=r_def),INTENT(IN) :: x !--incoming number, not allowed to be changed
INTEGER(kind=i_def),INTENT(IN) :: n !--ditto
REAL(kind=r_def),INTENT(OUT) :: y !--result of the subroutine

y = x**n

END SUBROUTINE

It's something I do for each subroutine. In times such as yours, you may get a nice pretty compiler error saying a variable has incorrect intent rather than the bane of us all...the seg fault.

p.s. There is also an INTENT(INOUT) which allows an incoming variable to be changed.

No, I didn't know of this command. It seems quite interesting. And you right. Segfault is as scary as hell.

D H said:
Whether you know it or not, you most certainly are. Those calls to read, write, sin, cos -- those are library functions. You didn't write those functions, did you? Those functions reside in a library -- in this case they are a part of the library provided au gratis by the language.

I most certainly did! But I whispered some of my codes to some IBM guy and he stole from me. At least he spent three years trying to understand them. :approve:
 

1. What is a Segmentation Fault?

A Segmentation Fault, also known as a segfault, is an error that occurs when a program attempts to access memory that it is not allowed to access. This can happen due to a bug in the program or incorrect memory management.

2. Why does a Segmentation Fault occur on Linux but not on Windows?

Linux and Windows are two different operating systems with different memory management systems. The way they handle memory and allocate resources can differ, which can result in a program running on one system without errors but encountering a segfault on the other.

3. What are some common causes of a Segmentation Fault on Linux?

Some common causes of a Segmentation Fault on Linux include trying to access a null pointer, accessing memory that has already been freed, stack overflow, or accessing memory outside the bounds of an array.

4. How can I debug a Segmentation Fault on Linux?

One way to debug a Segmentation Fault on Linux is by using a debugger tool such as gdb. This can help identify the specific line of code that is causing the error and provide more information about the memory access violation.

5. Can a Segmentation Fault be fixed on Linux?

Yes, a Segmentation Fault can be fixed on Linux by identifying and addressing the underlying cause of the error. This may involve debugging the code, fixing any memory management issues, or using tools such as valgrind to detect and fix memory errors.

Back
Top