作为我研究的一部分,我目前正在为Fortran90中一个讨厌的偏微分方程编写一个大的非线性求解器。我遇到了一个问题,我认为内存损坏问题困扰着我的代码而我正试图追踪它;这样做,我选择使用valgrind,因为这在过去对我有用。不幸的是,我在代码执行开始时收到一条无法解释的错误消息,请参阅下文:
==18257== Memcheck, a memory error detector
==18257== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18257== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==18257== Command: ./JFNKsolver
==18257==
==18257== Conditional jump or move depends on uninitialised value(s)
==18257== at 0x6F7F7D: __intel_sse2_strcpy (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x6AA1C0: for__open_proc (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x67EF6C: for__open_default (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x69878D: for_write_seq_lis (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x65BA69: MAIN__ (JFNKsolver.f90:146)
==18257== by 0x402DAD: main (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== Uninitialised value was created by a stack allocation
==18257== at 0x6AA07D: for__open_proc (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257==
==18257== Conditional jump or move depends on uninitialised value(s)
==18257== at 0x6F7F7D: __intel_sse2_strcpy (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x677DA5: for__add_to_lf_table (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x6ABA13: for__open_proc (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x67EF6C: for__open_default (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x69878D: for_write_seq_lis (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== by 0x65BA69: MAIN__ (JFNKsolver.f90:146)
==18257== by 0x402DAD: main (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257== Uninitialised value was created by a stack allocation
==18257== at 0x6AA07D: for__open_proc (in /home/cseinen/Documents/1_Thesis_Work/ThesisGit/Model/Source_Code/JFNKsolver)
==18257==
我通过使用valgrind --track-origins=yes ./JFNKsolver
运行我的代码来解决此错误。
现在我知道,通常,这些错误意味着在某个地方使用了一个未初始化的变量,但奇怪的是它出现在我的代码中真正发生的事情之前,它通过by 0x65BA69: MAIN__ (JFNKsolver.f90:146)
指向测试打印语句,即下面代码中的print *, "Test"
。
program JFNKsolver
use modelparams
use initialization
use forcing
use domain_routines
use solver_routines
use var_routines
use csv_file
use validation_routines
use validsoln_routines
implicit none
real(kind = dbl_kind) :: &
time, &
norm_test
integer(kind = int_kind) :: &
nxT, nyT, &
nxN, nyN, &
nxU, nyU, &
nxV, nyV, &
nt, &
nU_pnts, &
nV_pnts, &
nT_pnts, &
nN_pnts, &
nHT_pnts, &
nHN_pnts, &
si, &
tmp_size, &
i, j, ij
integer(kind = int_kind), allocatable, dimension (:) :: &
indxUi, indxUj, &
indxVi, indxVj, &
indxTi, indxTj, &
indxNi, indxNj, &
haloTi, haloTj, &
haloNi, haloNj
real(kind = dbl_kind), allocatable, dimension (:) :: &
Au, res_NL, u_update, &
b, b_0, vpb_forc
integer(kind = int_kind), allocatable, dimension (:,:,:) :: &
ulmsk, vlmsk, &
uimsk, vimsk, &
Timsk, Nimsk, &
Tlmsk, Nlmsk
real(kind = dbl_kind), allocatable, dimension (:,:) :: &
ugrid, vgrid, &
uResgrid, vResgrid, &
uocn_u, uocn_v, &
vocn_u, vocn_v, &
uwnd_u, uwnd_v, &
vwnd_u, vwnd_v, &
h_u, h_v, h_T, &
A_T, &
P_T, P_N, &
zeta_T, zeta_N, &
eta_T, eta_N, &
Cw_u, Cw_v, &
dist_T, dist_N, &
dist_gx_T, &
dist_gy_T
print *, "Test"
请注意,我已删除注释以清除它,并在modelparams模块中初始化类型变量。任何人都可以提供一些可能导致这种情况的见解吗?它可以通过use
语句链接到我正在使用的模块吗?我原本以为这是valgrind的一个问题,但现在我已经看到了内存损坏的影响,而且事实上这是我所看到的唯一错误,我已经对它保持警惕。
注意:我认为存在内存损坏问题的原因是因为我看到我的求解器行为发生了变化,只是存在不应该改变任何内容的代码。这是我为帮助验证代码而添加的功能,并且我已对此进行了大量测试。
答案 0 :(得分:1)
史蒂夫莱昂内尔在Intel Developer Zone回答了同样的问题。
以下是使用的示例程序:
Program Main
implicit none
write(*,*) "123"
End Program
编译:
$ ifort -g main.f90
然后打电话给:
$ valgrind -v --track-origins=yes --leak-check=full ./a.out
Valgrind基本上返回与上面相同的输出。
以下是史蒂夫的回复。
是的,你是对的。您已隐式打开了一个文件,该文件需要已分配的内存。文件未关闭,因此在程序结束时仍会分配内存。即使文件已关闭(并且程序退出时存在隐式关闭,也不会释放所有的簿记内存.valgrind并不了解Fortran。
你可能无法摆脱所有的valgrind投诉。
所以,如果我是你,我会忽略这些警告并查看你可能拥有的任何其他警告。