|
|
|
|
| 段错误,问题是不是出在这里?请问如何解决?(附代码) |
 段错误,问题是不是出在这里?请问如何解决?(附代码) - onlyflyer1 [ 2006-08-25 16:07 | 3,242 byte(s)]
 Re: 段错误,问题是不是出在这里?请问如何解决?(附代码) - kolin [ 2006-09-14 18:32 | 375 byte(s)]
 Re: 段错误,问题是不是出在这里?请问如何解决?(附代码) - jlboy [ 2006-09-12 10:41 | 1,278 byte(s)]
 Re: 段错误,问题是不是出在这里?请问如何解决?(附代码) - onlyflyer1 [ 2006-08-27 00:05 | 52 byte(s)]
 Re: 段错误,问题是不是出在这里?请问如何解决?(附代码) - onlyflyer1 [ 2006-08-25 16:27 | 2,778 byte(s)]
|
|
|
|
[Original]
[Print]
[Top]
|
请看下面这个函数,经过调试发现在调用readdir_r时出现段错误。(代码中标注处)
我在想造成段错误的罪魁祸首是不是opendir这个函数?
DIR * opendir(const char * name);
opendir返回一个指针,真正的DIR结构是在全局变量中,所以说opendir不是线程安全的。
我这个函数是一个双重循环,打开一个目录后,然后对目录下的子目录再进行遍历,所以需要两次opendir,这会不会造成第二次opendir时取得的目录内容冲毁了第一次opendir的DIR结构,从而造成readdir_r在对DIR结构进行操作时引用了非法内存从而导致段错误。
我现在还不敢肯定问题究竟是什么引起的。如果真的是这个问题,请问如何解决?难道不能连续使用opendir吗?opendir函数并没有线程安全版本。
代码如下:
int GetPidAndAppName(char *cinode, char *name)
{
DIR *dirp;
struct dirent *direntp = malloc(sizeof(struct dirent) + _POSIX_PATH_MAX);
struct dirent *direntp1 = malloc(sizeof(struct dirent) + _POSIX_PATH_MAX);//free later
dirp = opendir("/proc");//第一次调用opendir
while ( (readdir_r(dirp, direntp, &direntp) == 0) && direntp != NULL ) //在这里出现段错误!!!!!!!!!!!!!!!
{
if ( (direntp->d_type == 4) && ( atoi(direntp->d_name) > 0) )//is a dir
{
#ifdef _DEBUG
printf("%s is a dir
", direntp->d_name);
#endif
char pathfd[80];
char cpid[8];
memset(cpid, 0, 8);
memset(pathfd, 0, 80);
sprintf(pathfd, "/proc/%s/fd", direntp->d_name);
#ifdef _DEBUG
printf("pathfd:%s
", pathfd);
#endif
strcpy(cpid, direntp->d_name);
#ifdef _DEBUG
printf("cpid:%s
", cpid);
#endif
DIR *dirpfd;
dirpfd = opendir(pathfd);//第二次调用opendir
if ( dirfd == NULL )
{
continue;
}
else
{
#ifdef _DEBUG
printf("open subdir success
");
#endif
while ( (readdir_r(dirpfd, direntp1, &direntp1) == 0) && direntp1 != NULL )
{
#ifdef _DEBUG
printf("enter while
");
#endif
if ( direntp1->d_type == 10 )//symbol link file
{
char buf[80];
memset(buf, 0, 80);
char pathinode[80];
memset(pathinode, 0, 80);
sprintf(pathinode, "%s/%s", pathfd, direntp1->d_name);
int sz = readlink(pathinode, buf, 80);
if ( strstr(buf, cinode) != NULL )
{
closedir(dirp);
closedir(dirpfd);
int pid = atoi(cpid);
return pid;
}
}
}
#ifdef _DEBUG
printf("this process isn't what we want
");
#endif
closedir(dirpfd);
}
}
}
closedir(dirp);
return 0;
}
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
我又写了一个小程序,基本上验证了上面的问题。这个小程序使用来遍历/proc文件系统
#include<sys/types.h>
#include<dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
DIR *dirp;
DIR *dirp1;
char path[128];
memset(path, 0, 128);
struct dirent *direntp = malloc(sizeof(struct dirent) + _POSIX_PATH_MAX);
struct dirent *direntp1 = malloc(sizeof(struct dirent) + _POSIX_PATH_MAX);
dirp = opendir("/proc/");
while ( (readdir_r(dirp, direntp, &direntp) == 0) && direntp != NULL )
{
printf("%s
", direntp->d_name);
if ( (direntp->d_type == 4) && ( atoi(direntp->d_name) > 0) )
{
sprintf(path, "/proc/%s", direntp->d_name);
dirp1 = opendir(path);
while ( (readdir_r(dirp1, direntp1, &direntp1) == 0) && direntp1 != NULL )
{
printf(" %s
", direntp1->d_name);
}
}
}
closedir(dirp);
}
下面是程序输出显示结果
.
..
vmnet
mdstat
asound
ide
crypto
key-users
swaps
kallsyms
dma
iomem
ioports
misc
acpi
fb
mtrr
irq
bus
tty
driver
fs
sys
sysvipc
net
sysrq-trigger
kcore
modules
diskstats
zoneinfo
vmstat
buddyinfo
slabinfo
interrupts
stat
partitions
cpuinfo
kmsg
mounts
execdomains
locks
cmdline
filesystems
devices
version
meminfo
uptime
loadavg
self
1
.
..
task
fd
environ
auxv
status
cmdline
stat
statm
maps
mem
seccomp
cwd
root
exe
mounts
smaps
attr
wchan
oom_score
oom_adj
2
段错误 //在第二次调用opendir后,在使用readdir就出现了断错误。。。
看来问题找到了,关键如何解决阿?请问有替代函数吗?
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
写成这样行不行?
#include<sys/types.h>
#include<dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
DIR *dirp;
DIR *dirp1;
char path[128];
memset(path, 0, 128);
struct dirent *direntp = malloc(sizeof(struct dirent) + _POSIX_PATH_MAX);
dirp = opendir("/proc/");
while ( (readdir_r(dirp, direntp, &direntp) == 0) && direntp != NULL ){
printf("%s
", direntp->d_name);
if ( (direntp->d_type == 4) && ( atoi(direntp->d_name) > 0) ){
sprintf(path, "/proc/%s", direntp->d_name);
dirp1 = opendir(path);
struct dirent *direntp1 = malloc(sizeof(struct dirent) + _POSIX_PATH_MAX);
while ( (readdir_r(dirp1, direntp1, &direntp1) == 0) && direntp1 != NULL ){
printf(" %s
", direntp1->d_name);
}
free(direntp1);
}
}
free(direntp);
closedir(dirp);
}
|
|
|
----
Linux爱好者
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
while ( (readdir_r(dirp, direntp, &direntp) == 0) && direntp != NULL ) //在这里出现段错误!!!!!!!!!!!!!!!
------------------>>>
while ( direntp != NULL && (readdir_r(dirp, direntp, &direntp) == 0) )
看下效果如何
|
|
|
[Original]
[Print]
[Top]
|
|
|