Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29331 Discussions

ifort v 14.0 / 15.0 "-g" option causes segFault

John_H_18
Débutant
1 402 Visites

I have a complicated Fortran program with multiple modules in many files. When I try to compile with either v14.0 and v15.0 using the -g flag, I segFault on the first line of the program. Removing the -g flag fixes the problem and there are no problems at runtime.

Some sample code is below

program Main
implicit none

REAL, PARAMETER :: Pi = 3.14159265359
integer,parameter :: ND = 2

real, parameter :: RL = 1.0E-6	!Boundary radius
real, parameter :: HN = 5.0E-6	!Length of included needle
real, parameter :: HL = 2.0E-6	!Tip height

real, parameter :: LTT = 3E-6	!Tip-to-tip distance

real, parameter :: RU = 0.5E-6	!Boundary radius
real, parameter :: HU = 1.5E-6	!feature height

real, parameter :: zLen = HN + HL + LTT + HU

real,parameter,dimension(ND) ::	Length = (/ 20E-6, zLen /)			!computational domain size (r,z)

! Grid Spacing
real, parameter, dimension(ND) :: delta = (/ 1.0E-8	, 1.0E-8 /)
integer, PARAMETER, dimension(ND) :: cells = Length / delta

real,parameter :: VApplied = -150

REAL, PARAMETER :: cathode_temperature = 1473.14		!Cathode Temperature 
REAL, parameter :: anode_temperature = 973.14			!Anode Temperature 
real :: Cathode_Voltage, Anode_Voltage

REAL, dimension(0:cells(1), 0:cells(2)) :: phi
REAL, dimension(0:cells(1), 0:cells(2)) :: temperature				!grid-wise gas temperature

integer:: i,j

phi = 0.0
temperature = 0.0

	Cathode_Voltage = VApplied
	Anode_Voltage = 0

forall(i=0:Cells(1), j=0:Cells(2), j <= nint(lowerBoundary(i * delta(1)) / delta(2)))
	phi(i,j) = Cathode_Voltage
	temperature(i,j) = cathode_temperature
end forall

forall(i=0:Cells(1), j=0:Cells(2), j >= nint(upperBoundary(i * delta(1)) / delta(2)))
	phi(i,j) = Anode_Voltage
	temperature(i,j) = anode_temperature
end forall

!forall(i=0:Cells(1), j=0:Cells(2), (j > nint(lowerBoundary(i * delta(1)) / delta(2))) .and. (j < nint(upperBoundary(i * delta(1)) / delta(2))))
!	phi(i,j) = Cathode_Voltage + (Anode_Voltage - Cathode_Voltage) * ((delta(2) * j - lowerBoundary(i * delta(1)) ) / ( upperBoundary(i * delta(1)) - lowerBoundary(i * delta(1)) ))
!	temperature(i,j) = cathode_temperature + (anode_temperature - cathode_temperature) * ((delta(2) * j - lowerBoundary(i * delta(1)) ) / ( upperBoundary(i * delta(1)) - lowerBoundary(i * delta(1)) ))
!end forall

contains
	pure function LowerRegion(r) result(k)
	
	implicit none
		real,intent(in) :: r
		integer :: k

		if (r < 0) then
			k = 0
		elseif (r < RL) then
			k = 1
		elseif (r >= RL) then
			k = 2
		elseif (r > R) then
			k = 3
		endif
	end function LowerRegion

	pure function UpperRegion(r) result(k)
	
	implicit none
		real,intent(in) :: r
		integer :: k
	
		if (r < 0) then
			k = 0
		elseif (r < RU) then
			k = 1
		elseif (r >= RU) then
			k = 2
		elseif (r > R) then
			k = 3
		endif
	end function UpperRegion


!!!!!!!!!!!! Define geometry for regions radially !!!!!!!!!!!!!!!!!!
	pure function lowerBoundary(r) result(z)
	
	implicit none
		real,intent(in) :: r
		real :: z

		if (LowerRegion(r) == 1) then
			z = HN + HL * (1.0 - (r / RL))
		elseif (LowerRegion(r) == 2) then
			z = 0.0
		endif
	!end function lowerBoundary_Scalar
	end function lowerBoundary

	pure function upperBoundary(r) result(z)
	
	implicit none
		real,intent(in) :: r
		real :: z

		if (UpperRegion(r) == 1) then
			z = zLen - HU * (1.0 - (r / RU))
		elseif (UpperRegion(r) == 2) then
			z = zLen
		end if
	end function upperBoundary

end program Main

 

0 Compliments
1 Solution
Kevin_D_Intel
Employé
1 402 Visites

This actually appears related to the opt-level -O0 which is implied by -g. The seg-fault is reproducible with just -O0. I will look into this further and report it to development for a deeper investigation and let you know what we find.

If you are needing to debug your larger app, the seg-fault can avoided using with -O1, and if needed you can throw additional options: -debug, -traceback, -g, etc.

(Internal tracking id: DPD200376283)

Voir la solution dans l'envoi d'origine

0 Compliments
5 Réponses
mecej4
Contributeur émérite III
1 402 Visites

There are probably thousands of instances where there is no problem compiling with -g, in contrast to your single case of seeing a seg-fault. It is only if you post details of the circumstances and, possibly, the sample code, that there will be grounds for investigating and fixing the problem.

[P.S.: When I wrote this comment, #1 had no code at all. The O.P.  edited his post and added the code later.]

0 Compliments
Kevin_D_Intel
Employé
1 403 Visites

This actually appears related to the opt-level -O0 which is implied by -g. The seg-fault is reproducible with just -O0. I will look into this further and report it to development for a deeper investigation and let you know what we find.

If you are needing to debug your larger app, the seg-fault can avoided using with -O1, and if needed you can throw additional options: -debug, -traceback, -g, etc.

(Internal tracking id: DPD200376283)

0 Compliments
John_H_18
Débutant
1 402 Visites

Switching to the -O1 optimization fixes the SegFault issue but it makes it so that my debugging program (Allinea DDT 4.2) does not advance linearly. Is there any other possible fixes?

0 Compliments
Kevin_D_Intel
Employé
1 402 Visites

Sorry. I tried a number of different things and I cannot find anything. The issue appears related to the FORALL. Only one is required to be present/active to cause the seg-fault. I will ask for Development's help in finding a possible work around.

0 Compliments
Kevin_D_Intel
Employé
1 402 Visites

Development found an underlying stack issue at -O0 and that the seg-fault occurs related to stack temps created for the FORALL statements. There are two other workarounds.

Workaround #1 is to increase stack size limit. I was successful with your test case using: ulimit -s unlimited
Workaround #2 is to use DO loops instead of FORALL, as follows:

do i=0,cells(1)
    do j=0,cells(2)
        if (j <= nint(lowerBoundary(i * delta(1)) / delta(2))) then
            phi(i,j) = Cathode_Voltage
            temperature(i,j) = cathode_temperature
        endif
        if (j >= nint(upperBoundary(i * delta(1)) / delta(2))) then
            phi(i,j) = Anode_Voltage
            temperature(i,j) = anode_temperature
        endif
    end do
end do

I will update again when I know more.

0 Compliments
Répondre