繁体   English   中英

Fortran 95 中的“总线错误”和“munmap_chunk():无效指针”

[英]“Bus Error” and “munmap_chunk(): Invalid Pointer” in Fortran 95

我正在开发一个 python 项目,出于效率原因,该项目通过 f2py 调用 fortran 子例程。

当我执行代码时,它会在看似随机(不一致)的点处出现分段错误错误。 使用故障处理faulthandler库,我将搜索范围缩小到Bus Errormunmap_chunk(): Invalid Pointer错误,尽管错误仍然不一致。

鉴于错误看似随机的性质,恐怕我无法提供 MWE。 我的 Fortran 代码是(删节 - 完整版在这里):

module event_rates
      contains
      subroutine event_rate_f95(events, edges, events_edges, lifetimes, lt_size, NBins)
            implicit none
            ! define input parameters
            ! define internal variables

            dtd = delay_time_distribution(lifetimes, edges, NBins)
            print *, "DTD generated"
            do i = 1, NBins+1
                  t1 = events_edges(i-1)
                  t2 = events_edges(i)
                  print *, "Ts done"

                  z1 = estimate_redshift(t1)
                  z2 = estimate_redshift(t2)

                  print *, 'computing sfr'

                  SFR = compute_SFR(z1, z2) / (1E-3) ** 3

                  print *, "about to enter inner loop"

                  do j = 0, i-1
                        ! do a computation
                  enddo

                  print *, "exited inner loop"
                  print *, i
            enddo
      end subroutine
end module event_rates

其中delay_time_distribution, estimate_redshift, compute_SFR是我之前定义的函数。 作为参考,每当我调用它时, NBins大约为 50。 在最近的 3 次处决中,它失败了:

1) i=20estimate_redshift()内,

2) 在delay_time_distribution() function中,

3) 在 Fortran 代码终止并将控制权返回给 Python 之后。

从阅读有关这些错误的背景信息来看,这似乎是一个 memory 管理问题,因为分段错误正在访问 memory 我无法访问,总线错误正在访问 memory 并且指针没有传递错误的munmap_chunk()免费指令。 但我依靠 Fortran 95 的内置 memory 管理来为我处理这个问题。 在代码执行时监控htop显示我的一个核心上的 CPU 使用率达到峰值,但 memory 使用率保持不变。

我的问题有两个:是什么导致了这些错误,一般来说如何进一步调试?

调试问题

有一个简单的调试方法:使用调试标志

您可能知道,如果您使用 gfortran 编译 FORTRAN,您可以将-fcheck=bounds传递给gfortran命令。 同样,您可以将--opt='-fcheck=bounds'传递给f2py3命令来调试问题。

这个具体问题

我试图访问错误的数组。 考虑 pastebin 的第 122 行:

bin_low = floor(NBins * (x1 - NBins) / (NBins))

如果x1 = 0 ,则bin_low = -NBins 其中,由于NBins (您拥有的垃圾箱数)为正数,因此变为负数。 您不能在 FORTRAN 中对具有负索引的数组进行索引——这正在访问无效的 memory,也就是段错误。

这里的解决方案是约束索引:

bin_low = max(1, floor(NBins * (x1 - NBins) / (NBins)))

这样,如果公式给您一个负箱,您将访问第一个箱。 (记住,FORTRAN 是 1-indexed)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM