Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Segmentation Fault on Linux, but not on Windows

  1. Jul 31, 2010 #1
    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 (Text):
    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
     
     
  2. jcsd
  3. Aug 1, 2010 #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.
     
  4. Aug 1, 2010 #3

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    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.
     
  5. Aug 1, 2010 #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.
     
  6. Aug 2, 2010 #5

    minger

    User Avatar
    Science Advisor

    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.
     
  7. Aug 2, 2010 #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.
     
  8. Aug 2, 2010 #7

    minger

    User Avatar
    Science Advisor

    Ah, are you familiar with the INTENT property of subroutine variables? e.g.
    Code (Text):

    ...
    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.
     
  9. Aug 2, 2010 #8

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    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.
     
  10. Aug 2, 2010 #9
    No, I didn't know of this command. It seems quite interesting. And you right. Segfault is as scary as hell.

    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:
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook