C-Fortran接口调用realpath触发global-buffer-overflow错误求助
问题原因
- 核心问题1:C语言字符串要求以
\0(空终止符)结尾,而Fortran字符串默认没有尾缀的空终止符。你直接将Fortran字符串relativePath传给C函数时,C的realpath函数会持续向后读取内存直到找到\0,触发了全局缓冲区越界访问,这正是ASAN报错的直接原因。 - 核心问题2:缺少错误处理逻辑,C的
realpath函数执行失败时会返回NULL,你没有做判断直接读取output的长度,可能触发空指针访问。 - 潜在问题:你定义的输出路径长度只有200字节,远小于Linux系统默认的
PATH_MAX(通常为4096),如果绝对路径过长会触发缓冲区溢出。
修复方案
1. 修改Fortran代码
需要在传递输入路径前手动添加C风格空终止符,同时调整输出路径长度,补充必要的参数属性声明:
module sysUtils !! Routines for different system utilities use iso_c_binding, only : c_char, c_int, c_null_char use iso_fortran_env, only: error_unit private :: error_unit interface subroutine getFullPath_s(rPath, aPath, n) bind(c, name='realpathFunc') !! Resolve absolute path from a relative path import :: c_char, c_int character(kind=c_char), intent(in) :: rPath(*) character(kind=c_char), intent(out) :: aPath(*) integer(kind=c_int), intent(out) :: n end subroutine getFullPath_s end interface contains character(len=4096) function getFullPath(relativePath) result(actualPath) !! Resolve absolute path from a relative path character(len=*), intent(in) :: relativePath integer(c_int) :: n ! 转成C风格空终止字符串再传给C函数 call getFullPath_s(trim(adjustl(relativePath))//c_null_char, actualPath, n) if (n == 0) then write(error_unit,*) "获取绝对路径失败,输入路径:", relativePath actualPath = '' return end if actualPath(n+1:) = '' end function getFullPath end module sysUtils
2. 修改C代码补充错误处理
#include <stdlib.h> #include <stdio.h> #include <string.h> void realpathFunc(const char * rPath, char * output, int * n){ char * res = realpath(rPath, output); // 处理realpath执行失败的情况 if (res == NULL) { *n = 0; if (output != NULL) output[0] = '\0'; return; } *n = strlen(output); }
3. 主程序无需修改,重新编译运行即可。
内容的提问来源于stack exchange,提问作者Eular
相关产品推荐
相关产品推荐

