1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Fortran segmentation fault

  1. Jul 19, 2011 #1
    1. I have a segmentation fault when I try to run a program I have written in Fortran. The compiler I used is gfortran. What typically causes a segmentation fault, and how do I find where the problem is? I know I should use a debugger, but I don't know which debugger I should use, how to get it, or how to use it (I don't know whether it is Fortran 95, 03 or 08--how do I find out?).
     
  2. jcsd
  3. Jul 19, 2011 #2

    vela

    User Avatar
    Staff Emeritus
    Science Advisor
    Homework Helper
    Education Advisor

    Generally, a segmentation fault is caused by trying to access a memory location you shouldn't. This can happen, for instance, if you declare an array to have 10 elements but try to access the 100th element.

    Debugging is a bit of an art. If the program isn't too complicated, the first thing I'd do is look carefully through the source code for obvious errors. You can also insert write statements to report the values of variables at various points in the program to make sure your algorithm is working the way you expect it to.

    As far as debuggers go, I can't really offer any advice as I've rarely needed to use one. Since gfortran is a Gnu product, I'd expect gdb to work with it, but a little Googling suggests that combination did not work too well in the past. Perhaps things have improved since then.
     
  4. Jul 20, 2011 #3
    I should probably add a little background. My code performs an algorithm on some data in an input file. But the code works perfectly for small files, and only segfaults for larger files. That doesn't seem to make sense if the problem is simply to do with an invalid location.
     
  5. Jul 20, 2011 #4

    Mark44

    Staff: Mentor

    Show us your code, and we can most likely figure out why it's generating an error.

    If you paste your code into the text window here, put a [ code] tag at the top of it, and a [ /code] tag at the bottom. Omit the space right after the left bracket, though.
     
  6. Jul 21, 2011 #5

    NascentOxygen

    User Avatar

    Staff: Mentor

    Segmentation faults are catch-alls, usually indicating Some Major Problem. Such as giving a library data of the wrong type, or anything totally unexpected, really.

    But it really points to there being problem with your approach to developing your computer program. You should start off with a program that does nothing much more complex than print Hello World, then add in extra code and calls to subroutines in measured steps, each time checking that it is still all working so far. :surprised: :smile: As soon as a compiler or runtime error shows up, :grumpy: you can immediately identify what changes/additions caused the error to arise.

    If you type up the whole program, and throw it all at the compiler, unless you are an accomplished programmer, there will be dozens of errors, most tiny, some major. It can pose a headache and be just too unwieldy to untangle.

    Start out modest, and build up towards your final masterpiece, with lots of testing along the way. It sounds arduous, but you soon pick up speed.

    I suppose you have successfully compiled small test programs with that compiler? If not, then the problem might not lie with the code you are writing at all, it might be that the compiler software itself isn't installed correctly on your PC.
     
  7. Jul 21, 2011 #6

    vela

    User Avatar
    Staff Emeritus
    Science Advisor
    Homework Helper
    Education Advisor

    That's exactly the type of situation that can cause a segfault. Say your program loads all the input data into an array and you wrote the program assuming that at most you'll have, say, 100 pieces of input data. There'd be no spot in the array for the 101st piece of data, which means your program tries to access a memory location beyond the end of the array, possibly causing a segmentation fault.
     
  8. Jul 22, 2011 #7

    NascentOxygen

    User Avatar

    Staff: Mentor

    I have a vague recollection that arrays can default to a small 'subscript', say maximum of 10, and if you need them to go to higher subscripts you need an explicit DIM statement. (Gee, it's a long time since I wrote anything in MNF.)
     
  9. Jul 22, 2011 #8
    That would make sense. My code deals with many arrays. One problem with my code (which may or may not have led to the segmentation fault) is that it doesn't seem to be portable. I started out using gfortran, and today I tried to use NAG (somebody told me that it was easier to debug). However, I suddenly couldn't even compile the program, and got this error:
    --
    Error: cell_vertexc_mod.f90, line 357: USE CELL_VERTEX in program-unit RECOUNT_MEMBER imports symbol RECOUNT_MEMBER
    detected at CELL_VERTEX@<end-of-statement>
    --

    I don't understand why this is an error. All I am doing here is using an interface in another file. Why wouldn't this be allowed?
     
    Last edited: Jul 22, 2011
  10. Jul 22, 2011 #9
    Thank you for offering to look at the code, but there's quite a lot of it (about 900 lines now), and I wouldn't want anyone to spend ages working their way through it when they have better things to do!
     
  11. Jul 22, 2011 #10

    gneill

    User Avatar

    Staff: Mentor

    Whatever compiler you use should have options to generate bounds checking code for arrays and other accesses. For gfortran, for example, the command line option -fcheck=bounds. It should catch your error and report a line number where it occurred.
     
  12. Jul 22, 2011 #11
    Do I use the command in runtime, or in compiling? I used it in runtime using:

    ./{program file} -fcheck=bounds

    Is that what the usual command is? Also, do you know of any gfortran manuals I can find? All I can find is this one: http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gfortran/index.html#toc_Invoking-GFORTRAN

    But I'm not really sure where to find the information I need. The layout is slightly confusing.

    Thanks!
     
  13. Jul 22, 2011 #12

    gneill

    User Avatar

    Staff: Mentor

    It would be a compile time option, since the compiler must generate code to check these things.

    Have a look http://gcc.gnu.org/onlinedocs/gcc-4.5.3/gfortran/Code-Gen-Options.html#Code-Gen-Options".
     
    Last edited by a moderator: Apr 26, 2017
  14. Jul 22, 2011 #13
    I tried it, but it didn't show any errors. I assume that this means that the array sizes are fine, although this seems to contradict the fact that the program only segfaults for larger files. Can you give me exact command you would use? I used:

    gfortran program_name -fcheck=bounds module1.f90 module2.f90 program_name.f90
     
  15. Jul 22, 2011 #14

    gneill

    User Avatar

    Staff: Mentor

    To me your command line looks okay. Sorry, not much more I can suggest at this point except looking for other similar debugging switches to enable. Without having the code in-hand, it's just shooting in the dark :smile:
     
  16. Jul 23, 2011 #15
    Thanks. I'll try some others on that link you sent me.
     
  17. Jul 27, 2011 #16
    Hi, I've managed to find where the problem is, but I can't see what it is. This is the function that appears to be causing the segfault. Can anyone tell me what the problem might be? Thanks!

    Code (Text):


    FUNCTION pairing (list1, list2, fbpt, last) RESULT (paired)
    use cell_test, except_this_one => pairing
    IMPLICIT NONE
    LOGICAL paired
    TYPE (cell), TARGET, INTENT(IN):: list1, list2  
    TYPE (cell), POINTER, INTENT(INOUT):: fbpt      
    TYPE (cell), POINTER, INTENT(INOUT):: last
    LOGICAL :: found = .FALSE.
    INTEGER :: i, j, k
    INTEGER, DIMENSION(2):: tedge
    TYPE (cell), POINTER :: pt1, pt2

    found = .FALSE.
    paired = .FALSE.
    pt1 => list1
    pt2 => list2

    !print *, "pairng #1"
    tedge = (/0,0/)

    loop2:DO while(associated(pt2))
       if(pt2%vertex(1) .eq. Tagged) then  
           pt2=> pt2%next
       end if


       if(pt1%myself%index .eq. pt2%myself%index) then      
          pt2 => pt2%next                
       end if

       if (.not. associated(pt2)) then
          found = .FALSE.
          paired = .FALSE.
          exit loop2
       end if

       call find_fedge (pt1%myself%vertex, pt2%myself%vertex, pt1%myself%vsize, pt2%myself%vsize, found, tedge)
       if (found) then
       write (7,*) "paring:: found, the edge is =", (tedge(i), i=1, 2)
       write ( 7, '(A8,8x,I3,1x,I3,1x,A4,1x,I3,1x,I3)') &
       "paring::",pt1%index,pt1%myself%index,"cell", pt2%index,pt2%myself%index
       write ( 7, '(A9,7x,15I5)')  "paring:1:",(pt1%myself%vertex(i), i=1, pt1%myself%vsize)
       write ( 7, '(A9,7x,15I5)')  "paring:2:",(pt2%myself%vertex(i), i=1, pt2%myself%vsize)
          tedge = (/0,0/)
          allocate(fbpt%myself)
          fbpt => fbpt%myself          
          nullify(fbpt%prev)
          nullify(fbpt%next)
          nullify(fbpt%myself)          
          !print *, "pairng:: #8 %next => pt2, %prev => pt1"
          fbpt%next => pt2              
          fbpt%prev => pt1              
          fbpt%next%vertex(1) = Tagged  
          fbpt%prev%vertex(1) = Tagged  
          last => pt2                    
          paired = .TRUE.    
          exit loop2            
       else
          found = .FALSE.
          paired = .FALSE.
          pt2 =>pt2%next                  
       end if  

    END DO loop2


    END FUNCTION pairing

     
    The rest of the code (including those bits that it uses and calls) seems to be fine. It's just this function.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook