簡體   English   中英

Fortran-nf90_open-SIGSEGV

[英]Fortran - nf90_open - SIGSEGV

我正在使用提供給我的舊的fortran程序打開netcdf文件,讀取其內容,執行一些計算和內插,然后將數據寫入另一種文件格式。 我在fortran方面的經驗很少,因此,請提供任何幫助將不勝感激。

該程序已成功編譯:

ifort -c -CB -CU -ftrapuv -par_report0 -vec_report0 -heap-arrays -O0 -stand f90 -check all -traceback -fstack-protector -assume protect_parens -implicitnone -debug -gen-interfaces -check arg_temp_created -ftrapuv -g -convert big_endian -I/opt/cray/netcdf/4.3.0/INTEL/130/include/ CAM_netcdf_to_WRF_intermediate.f90 ; ifort CAM_netcdf_to_WRF_intermediate.o -L/opt/cray/netcdf/4.3.0/INTEL/130/lib -lnetcdf -lnetcdff

程序崩潰,嘗試讀取netcdf文件時超出范圍:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7657d33 in nf_open_ (A1=0x18 <Address 0x18 out of bounds>, A2=0x4e04bc <__NLITPACK_19>,
    A3=0x7fffffff90ec, C1=128) at fort-control.c:27
27      fort-control.c: No such file or directory.

使用“ bt full”運行GDB:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7657d33 in nf_open_ (A1=0x18 <Address 0x18 out of bounds>, A2=0x4e04bc <__NLITPACK_19>,
    A3=0x7fffffff90ec, C1=128) at fort-control.c:27
27      fort-control.c: No such file or directory.
(gdb) bt full
#0  0x00007ffff7657d33 in nf_open_ (A1=0x18 <Address 0x18 out of bounds>,
    A2=0x4e04bc <__NLITPACK_19>, A3=0x7fffffff90ec, C1=128) at fort-control.c:27
        B1 = 0x0
        B3 = 5113020
#1  0x00007ffff76630ac in NETCDF::nf90_open (
    path=<error reading variable: Cannot access memory at address 0x18>, mode=0, ncid=-858993460,
    chunksize=<error reading variable: Cannot access memory at address 0x0>,
    cache_size=<error reading variable: Cannot access memory at address 0x0>,
    cache_nelems=<error reading variable: Cannot access memory at address 0x0>,
    cache_preemption=<error reading variable: Cannot access memory at address 0x0>,
    comm=<error reading variable: Cannot access memory at address 0x0>,
    info=<error reading variable: Cannot access memory at address 0x0>, .tmp.PATH.len_V$ffc=128)
    at netcdf4_file.f90:64
        nf90_open = -144388088
        ret = 0
        preemption_out = 0
        nelems_out = -1
        size_out = 0
        preemption_in = 32767
        nelems_in = -134664192
        size_in = 32767

該程序如下:

program CAM_netcdf_to_WRF_intermediate
  use netcdf
  implicit none

  ! Declarations:
  integer, parameter :: outfile_diagnostics = 16
  integer, parameter :: infile_CAM_files_and_dates = 15
  character(len=24) :: HDATE

  ! dimensions:
  integer, parameter :: nx_CAM=288,ny_CAM=192,nz_CAM=26 &
       ,nfields=5,nfields2d=9,nfields2d_to_read=5 &
       ,nz_soil=4,nz_CLM=1,nfields_soil=2
  integer, parameter :: nz_WRF=38
  character(len=128) :: netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename
  character(len=128) :: netcdf_ice_filename
  integer :: iEOF
  logical :: EOF

  ! open outpuf log file:
  open(outfile_diagnostics,form='formatted',file="Output/CCSM2WRF.log")

  ! read the first date and netcdf file name from the input file:
  open(infile_CAM_files_and_dates,form='formatted',file="Input/CCSM2WRF.input")
  read(infile_CAM_files_and_dates,*,iostat=iEOF) netcdf_cam_filename,netcdf_clm_filename,&
                        netcdf_pop_filename,netcdf_ice_filename,hdate
  if (iEOF<0) then;
print *, "EOF True"
     EOF=.true.;
  else;
print *, "EOF False"
     EOF=.false.;
  end if

     call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
                    ,netcdf_clm_filename,netcdf_pop_filename &
                    ,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
  stop
end program CAM_netcdf_to_WRF_intermediate

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE HANDLE_ERR(STATUS)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  use netcdf
  implicit none
  INTEGER STATUS
  IF (STATUS .NE. NF90_NOERR) THEN
     PRINT *, NF90_STRERROR(STATUS)
     STOP 'Stopped'
  ENDIF
END SUBROUTINE HANDLE_ERR

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine dummy_read &
     (nz_WRF,outfile_diagnostics,netcdf_cam_filename &
     ,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename &
     ,nx_CAM,ny_CAM,nz_CAM)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  use netcdf
  implicit none
  integer :: nz_WRF
  integer :: nx_CAM,ny_CAM,nz_CAM
  character(len=128) :: filename
  character(len=24) :: HDATE
  integer :: outfile_diagnostics
  integer :: STATUS, NCID, NCID_clm, NCID_pop, NCID_ice
  character(len=128) :: netcdf_cam_filename, netcdf_clm_filename, netcdf_pop_filename
  character(len=128) :: netcdf_ice_filename

  ! open output files for metgrid in WRF/WPS intermediate format:
  write(filename,'("Output/FILE:",A13)') hdate(1:13)
  write(outfile_diagnostics,*) "output intermediate file filename=",filename
  open(10,form='unformatted',file=filename)

  write(filename,'("Output/SST:",A13)') hdate(1:13)
  write(outfile_diagnostics,*) "output intermediate SST file filename=",filename
  open(11,form='unformatted',file=filename)

  STATUS = NF90_OPEN(netcdf_cam_filename, 0, NCID)
!  STATUS = NF90_OPEN(path = "Inputdata/ind/cam_CCSM4_historical_197909-197912-1979090100.nc", mode= 0, ncid = NCID)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
print *, "first status conditional statement"
  STATUS = NF90_OPEN(netcdf_clm_filename, 0, NCID_clm)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  STATUS = NF90_OPEN(netcdf_pop_filename, 0, NCID_pop)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  STATUS = NF90_OPEN(netcdf_ice_filename, 0, NCID_ice)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  status=NF90_CLOSE(NCID)
  status=NF90_CLOSE(NCID_clm)
  status=NF90_CLOSE(NCID_pop)
  status=NF90_CLOSE(NCID_ice)

print *, "Leaving dummy, going to MAIN"
  return
end Subroutine dummy_read

如果我對netcdf文件的路徑進行硬編碼,則open語句有效(請參見dummy_read子例程中的注釋行)。 打印出main中的netcdf_cam_filename返回有效的字符串,但是打印出dummy_read子例程中的字符串則返回一個空字符串。 我不確定為什么netcdf_cam_filename字符串未正確將其放入子例程中。

請詢問您是否需要其他信息。 我只發布了我認為適用於該錯誤的部分代碼。 提前致謝。

您的子例程調用與實際定義不匹配。

您對dummy_read調用是:

call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
                ,netcdf_clm_filename,netcdf_pop_filename &
                ,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)

雖然您對dummy_read的聲明是:

Subroutine dummy_read &
 (nz_WRF,outfile_diagnostics,netcdf_cam_filename &
 ,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename &
 ,nx_CAM,ny_CAM,nz_CAM)

或以其他方式顯示:

call       dummy_read(nz_WRF,hdate,              outfile_diagnostics,netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM)
Subroutine dummy_read(nz_WRF,outfile_diagnostics,netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename,netcdf_ice_filename,nx_CAM,             ny_CAM,nz_CAM)

這導致參數不匹配。 虛擬參數outfile_diagnostics與實際參數hdate相關聯,依此類推。 您正在將10個參數傳遞給聲明為9的子例程。


您可能想知道為什么在這種情況下編譯器會生成可執行文件而不是產生錯誤。 這是因為您正在使用隱式接口調用該過程,並且Fortran信任您可以做正確的事情。 Fortran可以檢測參數不匹配,但是要這樣做,您需要提供一個顯式接口。 除了顯式聲明接口外,最簡單的方法是使該過程成為模塊過程(通過將子例程放入模塊中)或內部過程(通過將該過程放入contains語句之后的主程序contains )。

您也可以要求編譯器提供高級警告,以避免出現此問題。 使用-Wall用gfortran編譯會在您的代碼中產生以下警告:

     call dummy_read(nz_WRF,hdate,outfile_diagnostics,netcdf_cam_filename &
                            1
Warning: Type mismatch in argument 'outfile_diagnostics' at (1); passed CHARACTER(1) to INTEGER(4)

通常,ifort提供選項-gen-interfaces標志,該標志將自動生成包含外部過程的模塊。 但是,我認為這是一個將代碼移植到較新的語言標准的工具,而不是要依賴的工具。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM