删除调试打印后出现分段错误
Segmentation fault after removing debug printing
我有一个(对我来说)非常奇怪的分段错误。起初,我认为这是我的 4 个内核之间由于 openmp 的干扰,但是从等式中删除 openmp 不是 我想要的。事实证明,当我这样做时,segfault 仍然会发生。
奇怪的是,如果我在 inner-do 中的任何地方添加 print 或 write,它就会起作用。
subroutine histogrambins(rMatrix, N, L, dr, maxBins, bins)
implicit none;
double precision, dimension(N,3), intent(in):: rMatrix;
integer, intent(in) :: maxBins, N;
double precision, intent(in) :: L, dr;
integer, dimension(maxBins, 1), intent(out) :: bins;
integer :: i, j, b;
double precision, dimension(N,3) :: cacheParticle, cacheOther;
double precision :: r;
do b= 1, maxBins
bins(b,1) = 0;
end do
!$omp parallel do &
!$omp default(none) &
!$omp firstprivate(N, L, dr, rMatrix, maxBins) &
!$omp private(cacheParticle, cacheOther, r, b) &
!$omp shared(bins)
do i = 1,N
do j = 1,N
!Check the pair distance between this one (i) and its (j) closest image
if (i /= j) then
!should be faster, because it doesn't have to look for matrix indices
cacheParticle(1, :) = rMatrix(i,:);
cacheOther(1, :) = rMatrix(j, :);
call inbox(cacheParticle, L);
call inbox(cacheOther, L);
call closestImage(cacheParticle, cacheOther, L);
r = sum( (cacheParticle - cacheOther) * (cacheParticle - cacheOther) ) ** .5;
if (r /= r) then
! r is NaN
bins(maxBins,1) = bins(maxBins,1) + 1;
else
b = floor(r/dr);
if (b > maxBins) then
b = maxBins;
end if
bins(b,1) = bins(b,1) + 1;
end if
end if
end do
end do
!$omp end parallel do
end subroutine histogramBins
我在 f2py 命令中启用了 -debug-capi:
f2py --fcompiler=gfortran --f90flags="-fopenmp -fcheck=all" -lgomp --debug-capi --debug -m -c modulename module.f90;
这给了我这个:
debug-capi:Fortran subroutine histogrambins(rmatrix,&n,&l,&dr,&maxbins,bins)'
At line 320 of file mol-dy.f90
Fortran runtime error: Aborted
它还进行大量其他检查,列出给定的参数和调用的其他子例程等等。
反正调用的两个子程序都是非并行子程序。我在其他几个子程序中使用它们,我认为最好不要用另一个子程序的并行代码调用一个并行子程序。因此,在处理此函数时,没有其他函数应该处于活动状态。
这是怎么回事?添加 "print *, ;"" 如何导致段错误消失?
感谢您的宝贵时间。
打印语句影响并创建或删除段错误的情况并不少见。原因是它们改变了内存的布局方式,以便为正在打印的字符串腾出空间,或者如果你正在做一些格式化,你将为临时字符串腾出空间。该更改可能足以导致错误在第一次出现时崩溃或消失。
我看到你是从 Python 打电话来的。如果您使用 Linux - 您可以尝试遵循 a guide to using a debugger with Fortran called from Python 并找到导致崩溃的行和数据值。此方法也适用于 OpenMP。您也可以尝试使用 GDB 作为调试器。
如果没有您问题的源代码,我认为您不太可能 "answer" 回答这个问题 - 但希望上述想法能帮助您自己解决这个问题。
使用调试器(以我的经验)比使用 print 语句更不可能出现这种现在你看到它现在你不这样做的行为(如果只使用一个线程,几乎可以肯定是这样) .
我有一个(对我来说)非常奇怪的分段错误。起初,我认为这是我的 4 个内核之间由于 openmp 的干扰,但是从等式中删除 openmp 不是 我想要的。事实证明,当我这样做时,segfault 仍然会发生。
奇怪的是,如果我在 inner-do 中的任何地方添加 print 或 write,它就会起作用。
subroutine histogrambins(rMatrix, N, L, dr, maxBins, bins)
implicit none;
double precision, dimension(N,3), intent(in):: rMatrix;
integer, intent(in) :: maxBins, N;
double precision, intent(in) :: L, dr;
integer, dimension(maxBins, 1), intent(out) :: bins;
integer :: i, j, b;
double precision, dimension(N,3) :: cacheParticle, cacheOther;
double precision :: r;
do b= 1, maxBins
bins(b,1) = 0;
end do
!$omp parallel do &
!$omp default(none) &
!$omp firstprivate(N, L, dr, rMatrix, maxBins) &
!$omp private(cacheParticle, cacheOther, r, b) &
!$omp shared(bins)
do i = 1,N
do j = 1,N
!Check the pair distance between this one (i) and its (j) closest image
if (i /= j) then
!should be faster, because it doesn't have to look for matrix indices
cacheParticle(1, :) = rMatrix(i,:);
cacheOther(1, :) = rMatrix(j, :);
call inbox(cacheParticle, L);
call inbox(cacheOther, L);
call closestImage(cacheParticle, cacheOther, L);
r = sum( (cacheParticle - cacheOther) * (cacheParticle - cacheOther) ) ** .5;
if (r /= r) then
! r is NaN
bins(maxBins,1) = bins(maxBins,1) + 1;
else
b = floor(r/dr);
if (b > maxBins) then
b = maxBins;
end if
bins(b,1) = bins(b,1) + 1;
end if
end if
end do
end do
!$omp end parallel do
end subroutine histogramBins
我在 f2py 命令中启用了 -debug-capi:
f2py --fcompiler=gfortran --f90flags="-fopenmp -fcheck=all" -lgomp --debug-capi --debug -m -c modulename module.f90;
这给了我这个:
debug-capi:Fortran subroutine histogrambins(rmatrix,&n,&l,&dr,&maxbins,bins)'
At line 320 of file mol-dy.f90
Fortran runtime error: Aborted
它还进行大量其他检查,列出给定的参数和调用的其他子例程等等。
反正调用的两个子程序都是非并行子程序。我在其他几个子程序中使用它们,我认为最好不要用另一个子程序的并行代码调用一个并行子程序。因此,在处理此函数时,没有其他函数应该处于活动状态。
这是怎么回事?添加 "print *, ;"" 如何导致段错误消失?
感谢您的宝贵时间。
打印语句影响并创建或删除段错误的情况并不少见。原因是它们改变了内存的布局方式,以便为正在打印的字符串腾出空间,或者如果你正在做一些格式化,你将为临时字符串腾出空间。该更改可能足以导致错误在第一次出现时崩溃或消失。
我看到你是从 Python 打电话来的。如果您使用 Linux - 您可以尝试遵循 a guide to using a debugger with Fortran called from Python 并找到导致崩溃的行和数据值。此方法也适用于 OpenMP。您也可以尝试使用 GDB 作为调试器。
如果没有您问题的源代码,我认为您不太可能 "answer" 回答这个问题 - 但希望上述想法能帮助您自己解决这个问题。
使用调试器(以我的经验)比使用 print 语句更不可能出现这种现在你看到它现在你不这样做的行为(如果只使用一个线程,几乎可以肯定是这样) .