Syscall 参数 getcwd(buf) 指向不可寻址的字节

Syscall param getcwd(buf) points to unaddressable byte(s)

提问人:DravStart 提问时间:11/1/2023 最后编辑:DravStart 更新时间:11/1/2023 访问量:56

问:

我是第一次使用 valgrind 测试程序。我没有找到有关此错误的任何帮助。我做错了什么?我该如何解决?

最小可重复示例:

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>


int main(){
   char* dir = "testdir";
   mkdir(dir,0777);
   char* buf = calloc(1, sizeof(char)*255);
   char* directory = realpath(dir, buf);
   printf("%s\n", directory);
   free(buf);
}

valgrind 报告:

==18518== Syscall param getcwd(buf) points to unaddressable byte(s)
==18518==    at 0x4969AF2: getcwd (getcwd.c:78)
==18518==    by 0x48AD520: realpath@@GLIBC_2.3 (canonicalize.c:88)
==18518==    by 0x109216: main (in /home/sol/Documents/SOLProject/.test/a.out)
==18518==  Address 0x4a5013f is 0 bytes after a block of size 255 alloc'd
==18518==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==18518==    by 0x1091FF: main (in /home/sol/Documents/SOLProject/.test/a.out)
==18518== 
/home/sol/Documents/SOLProject/.test/testdir
==18518== 
==18518== HEAP SUMMARY:
==18518==     in use at exit: 0 bytes in 0 blocks
==18518==   total heap usage: 2 allocs, 2 frees, 1,279 bytes allocated
==18518== 
==18518== All heap blocks were freed -- no leaks are possible
==18518== 
==18518== For lists of detected and suppressed errors, rerun with: -s
==18518== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

C 马洛克 ·瓦尔格林德 getcwd

评论

0赞 Some programmer dude 11/1/2023
目标字符串的长度必须至少为字节。并且可能大于 。在这一点上,为什么要为动态分配内存?另外,请花一些时间详细研究realpath手册页PATH_MAXPATH_MAX255buf
0赞 DravStart 11/1/2023
@Someprogrammerdude它不大于 255(它是打印的,它是),这不是这里的问题。动态 BUF 分配也是如此。/home/sol/Documents/SOLProject/.test/testdir
1赞 Some programmer dude 11/1/2023
目标必须至少为 ,如手册页中所述。实际路径可能更小并不重要,缓冲区本身仍必须至少保持该大小。PATH_MAX
2赞 ikegami 11/1/2023
回复“它不大于 255”,没关系。你要传递字符。这显然是问题所在,因为它无法访问第 256 个字节(“[您分配的块]大小为 255 的块后 0 个字节”)PATH_MAX
1赞 Oka 11/1/2023
@gregspears 您强调的是尝试修改与字符串文字关联的内存时出现的未定义行为,这不是问题中存在的问题。如果字符串文本的类型是 ,则使用 a 指向字符串文本是完全有效的。因此,虽然不应该做任何事情,并且在此程序中是等效的,但限定数据(如 )将更好地显示意图,并在您尝试修改所述数据时发出警告。char *char [N]char *dirchar dir[]constconst char *dir

答:

1赞 Paul Floyd 11/1/2023 #1

在 FreeBSD 13.2 上使用热的 valgrind 3.22 我得到

==12420== Syscall param __realpathat(buf) points to unaddressable byte(s)
==12420==    at 0x4994B1A: ??? (in /lib/libc.so.7)
==12420==    by 0x49CDC16: realpath (in /lib/libc.so.7)
==12420==    by 0x2019D3: main (so12.c:10)
==12420==  Address 0x545f13f is 0 bytes after a block of size 255 alloc'd
==12420==    at 0x4851725: calloc (vg_replace_malloc.c:1599)
==12420==    by 0x2019C2: main (so12.c:9)

正如评论中提到的,期望realpath

The resolved_path argument must point to a buffer capable of storing at
least PATH_MAX characters, or be NULL.

如果我更改为将 NULL 作为缓冲区realpath

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>


int main(){
   char* dir = "testdir";
   mkdir(dir,0777);
   char* directory = realpath(dir, NULL);
   printf("%s\n", directory);
   free(directory);
}

然后我没有错误。