C接口调用Netlib Fortran函数出现段错误及内存泄漏的处理方法
问题场景
通过C接口调用libport.a中的Netlib Fortran函数,执行istkin_()时触发段错误,后续dgqex_()调用时也出现同类问题,相关函数可参考Netlib Port官方站点及对应开源仓库实现。
编译、运行与调试命令
常规编译流程
- 生成C侧目标文件:
nvcc --compiler-options -fpie -g -use_fast_math --disable-warnings -Wno-deprecated-gpu-targets -c test_C4.c -lstdc++ - 链接生成可执行文件:
gfortran -fcheck=all,no-array-temps -fstack-protector-all -Wall -ggdb3 -Wno-main -fno-second-underscore -use_fast_math test_C4.o -L/usr/local/lib -lport - 直接运行:
./a.out
Valgrind内存检测命令
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./a.out
可复现问题的完整精简代码
// ----------------- # include <stdio.h> # include <math.h> # include <unistd.h> #include <stdlib.h> struct CSTAK; struct { double DS[4000]; int LS[8000]; int IS[8000]; } CSTAK; extern void istkin_(const int ,const int ); extern void dgqex_(int NQUAD,double PQUAD[],double WQ[]); int main(int argc, char **argv) { struct CSTAK; // 求积变量 const int NQUAD=25; int i; double PQUAD[NQUAD], WQ[NQUAD]; //Port变量 // double *PQUAD=(double*)malloc(NQUAD*sizeof(int)); // double *WQ=(double*)malloc(NQUAD*sizeof(int)); istkin_(4000,4);// netlib port 栈初始化 dgqex_(NQUAD,&PQUAD[1],&WQ[1]); // netlib port 高斯求积 for (i=0; i< NQUAD;i++) { printf("P[%d]=%lf\n",i,PQUAD[i] ); } // realloc(PQUAD, 0); // realloc(WQ,0); free(PQUAD); free(WQ); }
已观测到的问题现象
- 无论
PQUAD、WQ使用静态栈数组还是动态分配内存,均可触发段错误与内存泄漏问题 - Valgrind输出的堆内存统计信息:
==18301== HEAP SUMMARY: ==18301== in use at exit: 5,444 bytes in 17 blocks ==18301== total heap usage: 21 allocs, 4 frees, 13,584 bytes allocated
- 单独使用gfortran编译运行这两个Fortran函数时,编译与运行全流程无错误
- 重新构建libport库后,问题仍未解决
待明确的核心疑问
- C接口结合CUDA编译流程调用传统Fortran函数的适配性是否存在问题
- 段错误与内存泄漏的根本排查方向
- 问题是否与Fortran使用
&PQUAD(1)、C使用&PQUAD[0]的数组索引起始差异导致的传参错误有关
内容的提问来源于stack exchange,提问作者ambika29
相关产品推荐
相关产品推荐

