gpt4 book ai didi

c - 第二次调用 opendir 时出现段错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:53:32 28 4
gpt4 key购买 nike

一些背景:

我正在为 nginx(网络服务器)编写一个模块,允许在共享环境中即时设置根目录。我有一个包含其他目录的目录,每个托管用户一个;给定与请求域相关的目录路径,我需要确定它属于哪个用户。

--public_dir
---user_1
---user_2
----com/example/www/_public/
---user_3

www.example.com 转换为 com/example/www 并且该函数应返回“user_2”

问题:

我通过打开 public_dir、遍历它、检查每个一级目录(用户)是否存在 com/example/www/_public/并缓存结果来成功地做到了这一点。第一次调用该函数时,所有程序都按预期运行。第二次尝试再次打开 public_dir 时出现段错误(它已在上一个函数调用中成功关闭):

#define NGX_SHARED_ENV_SHARED_DIR "/var/www/public/"
#define NGX_SHARED_ENV_PUBLIC_DIR "_public"

char* ownerFromDir(char *dir){
char *owner;
char fullPath[strlen(NGX_SHARED_ENV_SHARED_DIR)+strlen(dir)+128];
struct dirent *e;
struct stat sb;

// ------------ERROR IN HERE----------------------------

fprintf(stderr, "Before opendir\n");
DIR *sharedDir = opendir(NGX_SHARED_ENV_SHARED_DIR);
fprintf(stderr, "After opendir\n");

// -----------------------------------------------------

if(sharedDir){
while((e=readdir(sharedDir))!=NULL){
//is the entry a directory?
if(e->d_type!=DT_DIR){
continue;
}
if(strcmp(e->d_name, ".")==0 || strcmp(e->d_name, "..")==0){
continue;
}
// build a path to check for /var/www/public/userX/com/example/www/_public
snprintf(fullPath, sizeof(fullPath), "%s%s/%s/%s", NGX_SHARED_ENV_SHARED_DIR, e->d_name, dir, NGX_SHARED_ENV_PUBLIC_DIR);
stat(fullPath, &sb);
//if a matching directory is found then copy the entry name into owner
if(S_ISDIR(sb.st_mode)){
int len = 1 + (int) strlen(e->d_name);
owner = (char*) malloc(sizeof(char)*len);
free(owner);
memcpy(owner, &(e->d_name), len);
break;
}
}
closedir(sharedDir);
}
return owner;
}

即使在使用 gcc -g 编译调试标志时,gdb 也不是很有用

Breakpoint 1, ownerFromDir (dir=0x603450 "com/example") at ngx_module.h:43
43 char* ownerFromDir(char *dir){
(gdb) step
45 char fullPath[strlen(NGX_SHARED_ENV_SHARED_DIR)+strlen(dir)+128];
(gdb) step
48 fprintf(stderr, "Before opendir\n");
(gdb) step
Before opendir
49 DIR *sharedDir = opendir(NGX_SHARED_ENV_SHARED_DIR);
(gdb) step
50 fprintf(stderr, "After opendir\n");
(gdb) step
After opendir
51 if(sharedDir){
(gdb) continue
Continuing.

Breakpoint 1, ownerFromDir (dir=0x60b4a0 "com/example2") at ngx_module.h:43
43 char* ownerFromDir(char *dir){
(gdb) step
45 char fullPath[strlen(NGX_SHARED_ENV_SHARED_DIR)+strlen(dir)+128];
(gdb) step
48 fprintf(stderr, "Before opendir\n");
(gdb) step
Before opendir
49 DIR *sharedDir = opendir(NGX_SHARED_ENV_SHARED_DIR);
(gdb) step

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a99df2 in ?? () from /lib/x86_64-linux-gnu/libc.so.6

编辑:回溯

(gdb) backtrace
#0 0x00007ffff7a99df2 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7a9b446 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff7a9dfc5 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff7ad651b in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x0000000000400aea in ownerFromDir (dir=0x60b4a0 "com/example2") at ./ngx_module.h:48
#5 0x0000000000400cb2 in ownerFromDom (domain=0x40116c "example2.com") at ./ngx_module.h:82
#6 0x0000000000400f3f in testOwner (domain=0x40116c "example2.com", expect=0x401150 "user2") at ./ngx_module.c:45
#7 0x0000000000400e27 in runTests () at ./ngx_module.c:29
#8 0x0000000000400d0b in main (argc=1, argv=0x7fffffffe708) at ./ngx_module.c:10

谁能给我指出正确的方向?

最佳答案

您的代码:

        if(S_ISDIR(sb.st_mode)){
int len = 1 + (int) strlen(e->d_name);
owner = (char*) malloc(sizeof(char)*len);
free(owner);
memcpy(owner, &(e->d_name), len);
break;
}

这导致:

return owner;

你已经释放了内存所以 memcpy() 是无效的(访问你无权访问的内存)并且返回至少是危险的并且可以说是无效的(你是传回指向已释放内存的指针)。

删除这段代码中的free()。谁知道调用代码出了什么问题,但一个比较合理的猜测是“你 free() 返回值”,这是一个双重释放,也是一个严重的禁忌。

如所写,memcpy() 很容易破坏您的堆;双重释放可能会破坏您的堆。因此,由于有两个堆损坏源,您很可能会因此在某处发生崩溃,而 opendir() 会进行内存分配,因此它可能是一个受害者。如果您在此之前进行内存分配,它可能会崩溃。

关于c - 第二次调用 opendir 时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18908874/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com