Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

segmentation fault in a complex software

Status
Not open for further replies.

Bosse7

Programmer
Aug 3, 2015
19
FR
Hi

I have programmed Fortran for almost 40 years, mainly in materials thermodynamics, and since a retired a few years ago I started to use the new Fortran standard with TYPE etc to write a free version a thermodynamcs software based on my previous experiences. This has now grown to become some 40000 lines but it can calculate very nice things like multicomponent equilibria, phase diagrams etc. The software has worked quite well until last week when I added a few new facilities and suddenly got a lot of "Segmentation faults" running my test files. I know this is an error which is hard to trace but I do not think I can arrange a simpler version of the program where the error ocuurs. But as the sofware is free I can send a version to anyone who is interested and has a lot of free time to try to help.

The error occurs both occationally (the same calculculation sometimes work, sometimes fails) but always in some circumstances, in particular when I try to deallocate arrays of TYPE defined structures (containing other allocatable arrays). I know I have a rather complex data structure and rather involved code but what you can do with thermodynamics can also be quite complex. The case where it (almost) always fails it is when deallocationg such an allocatable array containing other allocatable arrays. The deallocation does not fail when I have used only the first element of this array of structures. But I sometimes get the error in other parts of the software when doing plain calculations, not deallocating anything.

I use GNU Fortran version 4.8 on Windows.

Any hint how I could rearrange the data structure to be more stable is welcome. I can attach a zip file with the code if there is interest, an earlier version of the software is available on the opencalphad repository on github. That never had this error.

Best wishes

Bosse
 
The software has worked quite well until last week when I added a few new facilities and suddenly got a lot of "Segmentation faults" running my test files.
Could you not go back to the state before the last week and try to carefully figure out, what changes could cause the instability ?

Try some compiler switches which could give you a better hint when an error occurs:
-Wall -fbounds-check

Have you tried to compile the source only with GNU Fortran or with any other compiler too?
 
I guess that what I will eventually have to do. The code probably contains a lot of minor bugs as I can only test a small range of the possible conditions for its use. For the code I originally helped to develop we had more than 10 PhD students using and reporting errors as soon as we could release any update of the code. -fbounds-check and -finit-local-zero I already use, I will try -Wall, Thanks.

I am just using my own laptop some other users are using the code on Linux but I do not have access to that.

 
With some inspiration I reallized that I had an array of pointers (defined in the smart way of defining a type which is a pointer and then dimensioning this type as an array) and this pointed to some elements of the array which I tried to deallocate. I had not deallocated this array of pointers before I tried to deallocate the array they pointed to but when I did that (and fixed some small new bugs) my deallocation works!

Not that I really think the Fortran runtime system cares that there are pointers to some some array elements in an array of TYPE structures when I try to deallocate the array ... but one never knows.

OK, one small step, thanks again for the inspiration. I liked -Wall also

 
Clearly, you need to work your way out of deallocation in the correct direction...you just can't leave stuff hanging; basically, you DEALLOCATE in the order reverse to the one you ALLOCATEd.

Say, are you using any kind of version control? For such a large project, you should. 'git' is very popular and for a reason, it is really nice to work with.
 
Programming during the 30 years before git existed I developed my own technique of version control but it is not as elegant as git and I have tried to use git, I setup a copy on gitbub but I get confused with the terms, For the time being I am the only programmer anyway and at each large change I runs some 30 test cases. The segmentation fault error has not appeared until the change last week and that was a rather comples combination of several parts which have been developed more or less independently.

The structure where I keep the data for an equilibrium calculation is very complex containing many structures which are allocated and deallocated frequently but I agree I have to check I have nothing pointing to the structures I deallocate. As the error is spurious I guess it is due to using variables that have not been initiated correctly but with structures that is not easy to check.

One thing I wonder is why size(allocatable array) return arbitrary values if the array is not allocated. Is allocated(allocatable array) the only way to know if an array is allocated or not? Is there any reason why returning zero for size(...) would not be a simple way to indicate that the array is not allocated?
 
Can't hardly blame "size" if the object being queried had not been created yet. So, yes, it is probably the contents of some random place.

Zero size is not a simple way to answer for anything unknown and, yes, you should probably first test for allocation status. Zero-sized arrays, by the way, are a perfectly legit thing and you have probably taken advantage of such thing before...every time you have a section specified with variables and "know" that if the upper bound is less than the lower bound ( arr(i:j) for j<i ), nothing will happen or a zero-sized array will be returned.
 
One thing I wonder is why size(allocatable array) return arbitrary values if the array is not allocated.
I tried this example
Code:
real, allocatable, dimension(:) :: a

allocate(a(2))
a(1) = 1.0
a(2) = 2.0
a(10) = 3.0 ! This should not be accessed

write(*,*) 'After allocation:'
write(*,*) 'allocated(a)=', allocated(a)
write(*,*) 'size(a)=', size(a)
write(*,*) 'a(1)=', a(1), ', a(2)=', a(2), ', a(10)=', a(10)

deallocate(a)
write(*,*) 'After deallocation:'
write(*,*) 'allocated(a)=', allocated(a)
write(*,*) 'size(a)=', size(a)
write(*,*) 'a(1)=', a(1), ', a(2)=', a(2), ', a(10)=', a(10)
end
and after deallocation I still get the original size 2, but the elements cannot be accessed.
Code:
 After allocation:
 allocated(a)= T
 size(a)=           2
 a(1)=   1.00000000     , a(2)=   2.00000000     , a(10)=   0.00000000
[highlight] After deallocation:
 allocated(a)= F
 size(a)=           2
[/highlight]
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  6f610f4e
#1  6f6913eb
#2  004010f8
Is allocated(allocatable array) the only way to know if an array is allocated or not? Is there any reason why returning zero for size(...) would not be a simple way to indicate that the array is not allocated?
 
I only know this reliable way to find out if the array is allocated or not:
Code:
! process only if the array is allocated
[highlight]if (allocated(array)) then[/highlight]
  n = size(array)
  ...
else
  ! Error
  ...
end if
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top