You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran77代码触发Segmentation Fault(内存访问问题)求助

Fortran77 段错误(Segmentation Fault)排查分析

终端报错信息

Program received signal SIGSEGV, Segmentation fault.
0x0000000000f523b7 in bcvnmtn (xb=<error reading variable: Cannot access memory at address 0xc44a8000c3818>, 
    yb=<error reading variable: Cannot access memory at address 0xc5dc8000c5138>, nstp=0, npoints=0, tx=..., ty=..., anx=..., any=...) at ./bcvnmtn.F:14
14            tx(1) = xb(1+nstp) - xb(1)

触发段错误的子例程 bcvnmtn

subroutine bcvnmtn(xb,yb,nstp,npoints,tx,ty,anx,any)

c-----compute the vertex valued tangential and normal vector fields
c----- (tx,ty)(n) and (anx,any)(n) to the curve (xb,yb)((n-1)*nstp+1)
c----- for n=1 to npoints

cdir$ nolist
      include 'paramcom.h'
cdir$ list
      dimension xb(1),yb(1),tx(1),ty(1),anx(1),any(1)

c-----get tangent vector field

      tx(1) = xb(1+nstp) - xb(1)
      ty(1) = yb(1+nstp) - yb(1)

      in = 1
      do 100 n=2,npoints-1
        inp = in + 2*nstp
        tx(n) = (xb(inp) - xb(in))*0.5
        ty(n) = (yb(inp) - yb(in))*0.5
        in = in + nstp
  100 continue

      nlast = npoints
      ilast = 1 + (npoints-1)*nstp
      tx(nlast) = xb(ilast) - xb(ilast-nstp)
      ty(nlast) = yb(ilast) - yb(ilast-nstp)

c-----normalize to unit length and rotate to get normal vector

      do 200 n=1,npoints
        tl = sqrt( tx(n)**2 + ty(n)**2 )
        tx(n) = tx(n) / ( tl + tiny )
        ty(n) = ty(n) / ( tl + tiny )
        any(n) = tx(n)
        anx(n) = -ty(n)
  200 continue

      return
      end

调用 bcvnmtn 的子例程 bcsymgd

subroutine bcsymgd(xi,yi)

c-----compute ghost point locations along a symmetry boundary

cdir$ nolist
      include 'common.h'
      include 'inputcom.h'
      include 'pointer.h'
cdir$ list
      common /bcpoint/ idimfrm,jdimfrm,isttfrm,jsttfrm,nstpfrm,nofffrm,
     %                 idimtoo,jdimtoo,istttoo,jstttoo,nstptoo,nofftoo,
     %                 npoints
      dimension xi(0:idimfrm,0:jdimfrm),yi(0:idimfrm,0:jdimfrm)
      call bcvnmtn(xi(isttfrm,jsttfrm),yi(isttfrm,jsttfrm),
     %             nstpfrm,npoints,tangx,tangy,anormx,anormy)
      call bcdifvf(dispx(isttfrm,jsttfrm),dispy(isttfrm,jsttfrm),
     %             nofffrm,nstpfrm,
     %             xi(isttfrm,jsttfrm),yi(isttfrm,jsttfrm),
     %             (- nofftoo),nstpfrm,
     %             xi(isttfrm,jsttfrm),yi(isttfrm,jsttfrm),
     %             nofffrm,nstpfrm,npoints)
      call bctrflc(dispx(isttfrm,jsttfrm),dispy(isttfrm,jsttfrm),
     %             dispx(isttfrm,jsttfrm),dispy(isttfrm,jsttfrm),
     %             nstpfrm,npoints,tangx,tangy,anormx,anormy)
      call bcaddvf(xi(istttoo,jstttoo),yi(istttoo,jstttoo),
     %             nofftoo,nstptoo,
     %             dispx(isttfrm,jsttfrm),dispy(isttfrm,jsttfrm),
     %             nofffrm,nstpfrm,
     %             xi(isttfrm,jsttfrm),yi(isttfrm,jsttfrm),
     %             nofffrm,nstpfrm,npoints)

      return
      end

问题背景

  • bcsymgd 中的 xi 和 yi 为二维几何坐标数组,调用 bcvnmtn 时转换为一维数组 xb、yb 传入
  • 使用编译器:pgi/2020.4
  • 代码为老旧大型程序,修改权限有限

错误原因分析

从报错信息可见核心异常:

  1. nstp=0、npoints=0,直接导致子例程内数组访问逻辑完全失效,例如第14行的xb(1+nstp)虽未越界,但后续循环和末尾的数组索引计算会出现非法内存访问
  2. xb 和 yb 无法读取内存,说明传入的数组指针无效,大概率是isttfrm、jsttfrm超出xi、yi的数组范围,或nstpfrm、npoints未正确初始化

排查建议

  1. 检查公共块参数初始化:确认/bcpoint/公共块中的nstpfrm、npoints、isttfrm、jsttfrm在调用bcsymgd前已正确赋值,尤其npoints和nstpfrm不能为0
  2. 验证数组边界:检查xi(isttfrm,jsttfrm)的索引是否在xi的有效范围(0:idimfrm, 0:jdimfrm)内,索引越界会传入无效指针
  3. 开启编译边界检查:用PGI编译器的-C(数组边界检查)和-g(调试信息)选项重新编译,获取更详细的越界位置:
    pgf77 -g -C your_program.f -o your_program
    
  4. 调试跟踪参数值:用GDB在bcsymgd入口设断点,查看公共块参数实际值:
    gdb ./your_program
    break bcsymgd
    run
    print idimfrm, jdimfrm, isttfrm, jsttfrm, nstpfrm, npoints
    
  5. 检查输出数组维度:确认tangx、tangy、anormx、anormy的维度至少为npoints,避免写入越界

内容的提问来源于stack exchange,提问作者Surya Sarvajith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 15:06:46