记一次memmove造成的bug

 做MIT S6.801时,由于给定的环境中没有strcat函数,所以使用了memmove函数,导致一个字符串变量中的数据被覆盖。

代码的功能为实现一个简单find命令,查找目录下的目标文件的位置。使用递归对子目录进行遍历。

当进入到递归时,发现传入的path参数变成空字符串,所以无法与当前文件名进行比较。

如果改用malloc使用堆内存时,path变量不会变成空字符串。

一开始以为是局部变量作用域消失,但传入的path变量是一个地址,母函数没有运行完前,变量是不会销毁的。所以排除这个可能。

经过调试发现,是memmove中,将de.name内存复制的时候,将de.name后的空白内存复制过去,造成了dir变量的越界,覆盖了dir变量后的path变量的内存。

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#define BUF_SIZE 14
void find(char *dir,char *path);
char *cutoff(char *path);
int main(int argc, char *argv[]){
    if(argc < 2){
        exit(-1);
    }
    char path[BUF_SIZE];
    //char * path = (char *)malloc(BUF_SIZE*sizeof(char));
    char dir[BUF_SIZE];
    strcpy(dir,argv[1]);
    strcpy(path,argv[2]);
    find(dir,path);
    free(path);
    exit(0);
}

void find(char *dir, char *path){
    int fd;
    struct dirent de;
    struct stat st;
    fd = open(dir,0);
    if(fd < 0){
        fprintf(2,"open error\n");
        return;
    }

    if(fstat(fd,&st)<0){
        fprintf(2,"stat error\n");
        close(fd);
        exit(1);
    }
    char *p;
    int str_len;
    if(!strcmp(dir,"./a/b")){
        printf("%d\n",st.type);
    }
    switch(st.type){
        case T_FILE:
            p = cutoff(dir);
            if(!strcmp(p,path)){
                printf("%s%s",dir,path);
            }
            break;

        case T_DIR:
            printf("path %s\n",path);
            p = dir+strlen(dir);
            *p++ = '/';
            while((str_len = read(fd,(void *)&de,sizeof(de))) == sizeof(de)){
                if(str_len == 0)
                    return;
                if(de.inum == 0)
                    continue;
                if(!strcmp(de.name,".")||!strcmp(de.name,"..")){
                    continue;
                }
                //memmove(p,de.name,BUF_SIZE);
                memmove(p,de.name,strlen(de.name)+1);
                printf("path %s\n",path);

                if(!strcmp(de.name,path)){
                    printf("%s\n",dir);
                }
                stat(dir,&st);
                if(st.type == 1){
                    find(dir,path);
                }
            }
            break;
    }
}
char *cutoff(char *path){
    char *p;
    for(p = path+strlen(path);p >= path &&*p != '/';p--);
    p++;
    return p;
}

C语言给了程序员足够的自由,但使用C语言时,还是要十分小心!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值