scandir() 导致段错误,即使有有效的绝对路径?
scandir() resulting in segfault, even with valid absolute path?
我不确定我在这里遗漏了什么,但我已经盯着它看了很长一段时间了。在扫描看似有效的目录时,我似乎遇到了分段错误。我只是想打印所有目录条目和子目录条目。 gdb 运行 和回溯:
(gdb) run
Starting program: /home/p/C_projects/recursive_ls/a.out
Directory is now /home/p/C_projects/recursive_ls
In /home/p/C_projects/recursive_ls: a.out
In /home/p/C_projects/recursive_ls: recursive_ls.c
In /home/p/C_projects/recursive_ls: test
In /home/p/C_projects/recursive_ls: test_1
In /home/p/C_projects/recursive_ls: test_2
a.out,inode=265490,owner=1000,size=10328
recursive_ls.c,inode=265577,owner=1000,size=1296
test,inode=265508,owner=1000,size=4096
Directory is now /home/p/C_projects/recursive_ls/test
Program received signal SIGSEGV, Segmentation fault.
0x00000003 in ?? ()
(gdb) backtrace
#0 0x00000003 in ?? ()
#1 0xb7eb5d5c in __alloc_dir (fd=3, close_fd=close_fd@entry=true,
flags=flags@entry=0, statp=0x0) at ../sysdeps/posix/opendir.c:207
#2 0xb7eb5e6a in __opendirat (dfd=dfd@entry=-100,
name=name@entry=0x804b938 "/home/p/C_projects/recursive_ls/test")
at ../sysdeps/posix/opendir.c:152
#3 0xb7eb6c53 in __GI_scandirat (dfd=-100,
dir=0x804b938 "/home/p/C_projects/recursive_ls/test", namelist=0xbffff02c,
select=0x804862b <isSelect>, cmp=0x8048520 <alphasort@plt>)
at scandirat.c:62
#4 0xb7eb62ca in scandir (
dir=0x804b938 "/home/p/C_projects/recursive_ls/test", namelist=0xbffff02c,
select=0x804862b <isSelect>, cmp=0x8048520 <alphasort@plt>) at scandir.c:43
#5 0x080486c5 in getFiles (
path=0x804b938 "/home/p/C_projects/recursive_ls/test") at recursive_ls.c:23
#6 0x0804886c in getFiles (path=0x804b008 "/home/p/C_projects/recursive_ls")
at recursive_ls.c:40
#7 0x080488dd in main () at recursive_ls.c:48
(gdb)
现在,这个绝对路径 /home/p/C_projects/recursive_ls/test 似乎是合法的:
p@p-VirtualBox:~/C_projects/recursive_ls/test$密码
/home/p/C_projects/recursive_ls/test
代码在下面,有什么可以指点我的吗?:
#include <stdio.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
const int MAX_PATH = 255;
int isSelect(const struct dirent *file){
if(strcmp(file->d_name,".") == 0 || strcmp(file->d_name,"..") == 0)
return 0;
else
return 1;
}
void getFiles(char* path){
printf("\nDirectory is now %s", path);
printf("\n");
struct dirent** files;
struct stat *stat_;
int count = scandir(path, &files, isSelect, alphasort);
for(int i = 0; i < count; i++){
printf("\nIn %s: %s", path, files[i]->d_name);
}
for(int i = 0; i < count; i++){
char* tmp = malloc(MAX_PATH*2), *tmp1 = malloc(MAX_PATH);
strcat(strcpy(tmp1, path), "/");
strcat(strcat(strcpy(tmp,path), "/"), files[i]->d_name);
int statResult = stat(tmp, stat_);
if(statResult != 0){
printf("\nOh noes! I couldn't get stats on the file %s", files[i]->d_name);
}
else
printf("\n%s,inode=%lu,owner=%d,size=%lu"
,files[i]->d_name,stat_->st_ino,stat_->st_uid,stat_->st_size);
if(S_ISDIR(stat_->st_mode)){
strcat(tmp1, files[i]->d_name);
getFiles(tmp1);
}
}
}
int main(){
char* path = malloc(MAX_PATH);
getcwd(path, MAX_PATH);
getFiles(path);
}
这里没有报错,但是你的使用有问题stat
。因为这会覆盖堆栈,所以我敢打赌这就是原因。您正在传递 stat()
一个未初始化的指针变量。您应该传递一个指向变量的指针,例如:
struct stat stat_;
...
int statResult = stat (tmp, &stat_);
if (statResult != 0)
{
printf ("\nOh noes! I couldn't get stats on the file %s",
files[i]->d_name);
}
else
printf ("\n%s,inode=%lu,owner=%d,size=%lu", files[i]->d_name,
stat_.st_ino, stat_.st_uid, stat_.st_size);
if (S_ISDIR (stat_.st_mode))
...
有了这个,稍微移动了 for
循环中 int i
的声明,以及 main()
末尾的 exit(0)
,它编译了使用 -Wall -Werror
并且似乎可以工作(即下降目录)。
我不确定我在这里遗漏了什么,但我已经盯着它看了很长一段时间了。在扫描看似有效的目录时,我似乎遇到了分段错误。我只是想打印所有目录条目和子目录条目。 gdb 运行 和回溯:
(gdb) run
Starting program: /home/p/C_projects/recursive_ls/a.out
Directory is now /home/p/C_projects/recursive_ls
In /home/p/C_projects/recursive_ls: a.out
In /home/p/C_projects/recursive_ls: recursive_ls.c
In /home/p/C_projects/recursive_ls: test
In /home/p/C_projects/recursive_ls: test_1
In /home/p/C_projects/recursive_ls: test_2
a.out,inode=265490,owner=1000,size=10328
recursive_ls.c,inode=265577,owner=1000,size=1296
test,inode=265508,owner=1000,size=4096
Directory is now /home/p/C_projects/recursive_ls/test
Program received signal SIGSEGV, Segmentation fault.
0x00000003 in ?? ()
(gdb) backtrace
#0 0x00000003 in ?? ()
#1 0xb7eb5d5c in __alloc_dir (fd=3, close_fd=close_fd@entry=true,
flags=flags@entry=0, statp=0x0) at ../sysdeps/posix/opendir.c:207
#2 0xb7eb5e6a in __opendirat (dfd=dfd@entry=-100,
name=name@entry=0x804b938 "/home/p/C_projects/recursive_ls/test")
at ../sysdeps/posix/opendir.c:152
#3 0xb7eb6c53 in __GI_scandirat (dfd=-100,
dir=0x804b938 "/home/p/C_projects/recursive_ls/test", namelist=0xbffff02c,
select=0x804862b <isSelect>, cmp=0x8048520 <alphasort@plt>)
at scandirat.c:62
#4 0xb7eb62ca in scandir (
dir=0x804b938 "/home/p/C_projects/recursive_ls/test", namelist=0xbffff02c,
select=0x804862b <isSelect>, cmp=0x8048520 <alphasort@plt>) at scandir.c:43
#5 0x080486c5 in getFiles (
path=0x804b938 "/home/p/C_projects/recursive_ls/test") at recursive_ls.c:23
#6 0x0804886c in getFiles (path=0x804b008 "/home/p/C_projects/recursive_ls")
at recursive_ls.c:40
#7 0x080488dd in main () at recursive_ls.c:48
(gdb)
现在,这个绝对路径 /home/p/C_projects/recursive_ls/test 似乎是合法的:
p@p-VirtualBox:~/C_projects/recursive_ls/test$密码 /home/p/C_projects/recursive_ls/test
代码在下面,有什么可以指点我的吗?:
#include <stdio.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
const int MAX_PATH = 255;
int isSelect(const struct dirent *file){
if(strcmp(file->d_name,".") == 0 || strcmp(file->d_name,"..") == 0)
return 0;
else
return 1;
}
void getFiles(char* path){
printf("\nDirectory is now %s", path);
printf("\n");
struct dirent** files;
struct stat *stat_;
int count = scandir(path, &files, isSelect, alphasort);
for(int i = 0; i < count; i++){
printf("\nIn %s: %s", path, files[i]->d_name);
}
for(int i = 0; i < count; i++){
char* tmp = malloc(MAX_PATH*2), *tmp1 = malloc(MAX_PATH);
strcat(strcpy(tmp1, path), "/");
strcat(strcat(strcpy(tmp,path), "/"), files[i]->d_name);
int statResult = stat(tmp, stat_);
if(statResult != 0){
printf("\nOh noes! I couldn't get stats on the file %s", files[i]->d_name);
}
else
printf("\n%s,inode=%lu,owner=%d,size=%lu"
,files[i]->d_name,stat_->st_ino,stat_->st_uid,stat_->st_size);
if(S_ISDIR(stat_->st_mode)){
strcat(tmp1, files[i]->d_name);
getFiles(tmp1);
}
}
}
int main(){
char* path = malloc(MAX_PATH);
getcwd(path, MAX_PATH);
getFiles(path);
}
这里没有报错,但是你的使用有问题stat
。因为这会覆盖堆栈,所以我敢打赌这就是原因。您正在传递 stat()
一个未初始化的指针变量。您应该传递一个指向变量的指针,例如:
struct stat stat_;
...
int statResult = stat (tmp, &stat_);
if (statResult != 0)
{
printf ("\nOh noes! I couldn't get stats on the file %s",
files[i]->d_name);
}
else
printf ("\n%s,inode=%lu,owner=%d,size=%lu", files[i]->d_name,
stat_.st_ino, stat_.st_uid, stat_.st_size);
if (S_ISDIR (stat_.st_mode))
...
有了这个,稍微移动了 for
循环中 int i
的声明,以及 main()
末尾的 exit(0)
,它编译了使用 -Wall -Werror
并且似乎可以工作(即下降目录)。