分段错误 - 无效的内存引用

时间:2015-01-30 11:10:17

标签: fortran lapack

嘿我试图让我的LAPACK库工作,我搜索和搜索但我似乎无法弄清楚我做错了什么。

我尝试运行我的代码,我收到以下错误

程序接收信号SIGSEGV:分段故障 - 内存参考无效。

Backtrace for this error:
#0  0x7FFB23D405F7
#1  0x7FFB23D40C3E
#2  0x7FFB23692EAF
#3  0x401ED1 in sgesv_
#4  0x401D0B in MAIN__ at CFDtest.f03:? Segmentation fault (core dumped)

我会在这里粘贴我的主要代码,希望有人可以帮我解决这个问题。

****************************************************
PROGRAM CFD_TEST

USE MY_LIB

IMPLICIT DOUBLE PRECISION (A-H,O-Z)

DIMENSION ET(0:10), VN(0:10), WT(0:10)

DIMENSION SO(0:10), FU(0:10), DMA(0:10,0:10)

DIMENSION DMA2(0:10,0:10), QN(0:10), WKSPCE(0:10)

INTEGER*8 :: pivot(10), inf

INTEGER*8 :: N

EXTERNAL SGESV

!SET THE PARAMETERS

SIGMA1 = 0.D0

SIGMA2 = 0.D0

TAU = 1.D0

EF  = 1.D0

EXP  = 2.71828182845904509D0

COST = EXP/(1.D0+EXP*EXP)

DO 1 N=2, 10

!COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX

CALL ZELEGL(N,ET,VN)   

CALL WELEGL(N,ET,VN,WT)  

CALL DMLEGL(N,10,ET,VN,DMA)


!CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE

!DIFFERENTIAL OPERATOR

DO 2 I=0, N

DO 2 J=0, N

SUM = 0.D0

DO 3 K=0, N

SUM = SUM + DMA(I,K)*DMA(K,J)

3 CONTINUE

OPER = -SUM

IF(I .EQ. J) OPER = -SUM + TAU

DMA2(I,J) = OPER

2 CONTINUE

!CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE

!BOUNDARY CONDITIONS

DO 4 J=0, N

DMA2(0,J) = 0.D0

DMA2(N,J) = 0.D0


4 CONTINUE

DMA2(0,0) = 1.D0

DMA2(N,N) = 1.D0


!CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR

DO 5 I=1, N-1 

FU(I) = EF

5 CONTINUE

FU(0) = SIGMA1

FU(N) = SIGMA2

!SOLUTION OF THE LINEAR SYSTEM

N1 = N + 1

CALL SGESV(N,N,DMA2,pivot,FU,N,inf)

DO 6 I = 0, N

FU(I) = SO(I)

6 CONTINUE

PRINT *, pivot

1 CONTINUE

RETURN

END PROGRAM CFD_TEST

*****************************************************

我运行编译的命令是

gfortran -c MY_LIB.f03

gfortran -c CFDtest.f03

gfortran MY_LIB.o CFDtest.o -o CFDtest -L / usr / local / lib -llapack -lblas


我运行了命令

-fbacktrace -g -Wall -Wextra CFDtest

CFDtest:在函数_fini': (.fini+0x0): multiple definition of _ fini'中 /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/ x86_64 / crti.S:80:首先在这里定义 CFDtest:在函数data_start': (.data+0x0): multiple definition of data_start'中 /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.data+0x0):首先在这里定义 CFDtest:在函数data_start': (.data+0x8): multiple definition of __ dso_handle'中 /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o:(.data+0x0):首先在这里定义 CFDtest :(。rodata + 0x0):_IO_stdin_used' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here CFDtest: In function _ start'的多重定义: (.text + 0x0):_start' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here CFDtest: In function _ init'的多重定义: (.init + 0x0):_init' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:64: first defined here /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o:(.tm_clone_table+0x0): multiple definition of __ TMC_END '的多重定义 CFDtest :(。data + 0x10):首先在这里定义 / usr / bin / ld:CFDtest中的错误(.eh_frame);不会创建.eh_frame_hdr表。 collect2:错误:ld返回1退出状态

2 个答案:

答案 0 :(得分:2)

您尚未发布MY_LIB.f03的代码,因此我们无法完全按照您提供的方式编译CFDtest.f03

(顺便说一句,通常的命名约定是f90文件中的.f90不应该暗示语言版本是针对的。相反,.f90表示自由格式而{ {1}}用于固定格式。通过扩展,您的.f文件会更好(例如,如果更便于移植),则命名为.f03。)

我注释了.f90行并通过USE MY_LIB运行了您的代码。分解的输出是

nagfor -u -c cfd_test.f90

字节数不可移植。 8字节整数的Extension: cfd_test.f90, line 13: Byte count on numeric data type detected at *@8 Extension: cfd_test.f90, line 15: Byte count on numeric data type detected at *@8 值为kind。 (类似地,您可能希望为双精度数据使用selected_int_kind(18)种类值。)

kind(0.0d0)

你有这些隐式输入,这意味着它们是4字节(默认)整数。您可能应该将这些显式声明为8字节整数(使用上面的8字节整数种类值),如果这是您想要的。

Error: cfd_test.f90, line 48: Implicit type for I
       detected at 2@I
Error: cfd_test.f90, line 50: Implicit type for J
       detected at 2@J
Error: cfd_test.f90, line 54: Implicit type for K
       detected at 3@K
Error: cfd_test.f90, line 100: Implicit type for N1
       detected at N1@=

你需要决定你打算用这些做什么,或者它们是否只是可删除的。

使用显式声明的隐式整数,还有输出

Questionable: cfd_test.f90, line 116: Variable COST set but never referenced
Questionable: cfd_test.f90, line 116: Variable N1 set but never referenced
Warning: cfd_test.f90, line 116: Unused local variable QN
Warning: cfd_test.f90, line 116: Unused local variable WKSPCE

这看起来很糟糕。

Warning: cfd_test.f90, line 116: Variable SO referenced but never set

使用现代Obsolescent: cfd_test.f90, line 66: 2 is a shared DO termination label 终结符(不共享!),您的DO循环可能会更好。

END DO

这显然很容易解决。

对于LAPACK调用,这些例程的显式接口的一个来源是NAG Fortran库(通过Error: cfd_test.f90, line 114: RETURN is only allowed in SUBROUTINEs and FUNCTIONs 模块)。由于您的实际数据不是单一精度,因此您应该使用nag_library而不是dgesv。添加sgesv并切换为调用USE nag_library, ONLY: dgesv而不是dgesv,然后按上述方式重新编译,显示

sgesv

所以你确实应该使用默认(4字节整数) - 至少对你的系统上的LAPACK构建来说,这几乎肯定会使用4字节整数。因此,您可能希望忘记关于Incorrect data type INTEGER(KIND=4) (expected INTEGER) for argument N (no. 1) of DGESV 整数的所有内容,并且只使用默认的kind类型。纠正这个问题

integer

所以你需要添加这个参数。也许通过Array supplied for scalar argument LDA (no. 4) of DGESV

将此参数添加到调用中,代码成功编译,但如果没有size(DMA2,1)函数的定义,则无法进行任何运行时测试。

这是我程序的修改版(和漂亮打印版)

*LEGL

一般情况下,如果您使用尽可能好的检查编译器,那么您的开发经验将是最令人愉快的,如果您确保要求它尽可能多地为您进行诊断。

答案 1 :(得分:1)

据我所知,可能存在许多问题:

  • INTEGER*8的整数可能太长,可能会INTEGER*4或只是INTEGER会更好
  • 您在双参数上调用SGESV而不是DGESV
  • 您的LDA参数缺失,因此您的代码应该看起来像CALL DGESV(N,N,DMA2,N,pivot,FU,N,inf),但您需要检查这是否是您想要的。