操作系统 ----- 段错误(核心转储)
今天在linux下面编码程序的时候,出现了个错误 “已放弃(核心已转储)”,此前碰到过几次“段错误(核心已转储)”,做下笔记。
段错误(核心已转储):通常是内存越界造成的,可以检查是否使用了NULL的指针,或者数组越界。调试收到的信号是SIGSEGV。
已放弃(核心已转储):我碰到的这次是因为试图用free()函数释放一个全局变量。free只能释放用户申请在堆里的内存,用malloc()函数申请的内存就是在堆里面的,这些内存才能用free释放。使用的时候调用层次多了可能忘了这是一个全局变量。
附主程序代码:
1 /*主程序main()(文件名main.c)*/ 2 3 #include <string.h> 4 #include <stdio.h> 5 #include <arpa/inet.h> 6 #include "filesys.h" 7 #include <malloc.h> 8 #include<string.h> 9 struct hinode hinode[NHINO]; 10 struct dir dir; 11 struct file sys_ofile[SYSOPENFILE]; 12 struct filsys filsys; 13 struct pwd pwd[PWDNUM]; 14 struct user user[USERNUM]; 15 FILE * fd; 16 struct inode * cur_path_inode; 17 int user_id,file_block; 18 19 main() 20 { 21 unsigned short ab_fd1,ab_fd2,ab_fd3,ab_fd4; 22 unsigned short bhy_fd1; 23 char * buf; 24 printf("\nDo you want to format the disk?\n"); 25 if(getchar()=='y') 26 { 27 printf("Format will erase all context on the disk.Are you sure?\n"); 28 getchar(); 29 } 30 else 31 return; 32 if(getchar()=='y') 33 format(); 34 else 35 return; 36 install(); 37 _dir(); 38 login(2118,"abcd"); 39 user_id=0; 40 mkdir("a2118"); 41 chdir("a2118"); 42 ab_fd1=create(user_id,"file0.c",01777); 43 file_block=BLOCKSIZ * 6+5; 44 buf=(char *)malloc(BLOCKSIZ * 6+5); 45 write(ab_fd1,buf,BLOCKSIZ * 6+5); 46 close(user_id,ab_fd1); 47 free(buf); 48 //delete []buf; 49 50 51 mkdir("subdir"); 52 chdir("subdir"); 53 ab_fd2=create(user_id,"file1.c",01777); 54 file_block=BLOCKSIZ * 4+10; 55 buf=(char*)malloc(BLOCKSIZ*4+20); 56 write(ab_fd2,buf,BLOCKSIZ*4+20); 57 close(user_id,ab_fd2); 58 buf=NULL; 59 free(buf); 60 //delete []buf; 61 62 63 chdir(".."); 64 ab_fd3=create(user_id,"file2.c",01777); 65 file_block=BLOCKSIZ * 3+255; 66 buf=(char*)malloc(BLOCKSIZ*3+255); 67 write(ab_fd3,buf,BLOCKSIZ*3+255); 68 close(user_id,ab_fd3); 69 buf=NULL; 70 free(buf); 71 //delete []buf; 72 73 _dir(); 74 delete("ab_file0.c"); 75 76 ab_fd4=create(user_id,"file3.c",01777); 77 file_block=BLOCKSIZ * 8+300; 78 buf=(char*)malloc(BLOCKSIZ * 8+300); 79 write(ab_fd4,buf,BLOCKSIZ * 8+300); 80 close(user_id,ab_fd4); 81 buf=NULL; 82 free(buf); 83 //delete []buf; 84 85 86 _dir(); 87 ab_fd3=open(user_id,"file2.c",FAPPEND); 88 file_block=BLOCKSIZ * 3+100; 89 buf=(char*)malloc(BLOCKSIZ * 3+100); 90 write(ab_fd3,buf,BLOCKSIZ * 3+100); 91 close(user_id,ab_fd3); 92 buf=NULL; 93 free(buf); 94 //delete []buf; 95 96 _dir(); 97 chdir(".."); 98 logout(); 99 halt(); 100 }
在main函数中我加入了一些信息便于发现内存泄漏的所在,通过执行看结果,发现是format()方法出现了错误
附上format()方法:
1 ormat() 2 { 3 struct inode *inode; 4 struct direct dir_buf[BLOCKSIZ/(DIRSIZ+2)]; 5 struct filsys; 6 unsigned int block_buf[BLOCKSIZ/sizeof(int)]; 7 char *buf; 8 int i,j; 9 10 fd=fopen("filesystem","r+w+b"); 11 buf=(char* )malloc((DINODEBLK+FILEBLK+2)*BLOCKSIZ*sizeof(char)); 12 if(buf==NULL) 13 { 14 printf("\nfile system file create failed!\n"); 15 exit(0); 16 } 17 fseek(fd,0,SEEK_SET); 18 fwrite(buf,1,(DINODEBLK+FILEBLK+2)*BLOCKSIZ*sizeof(char),fd); 19 20 pwd[0].p_uid=2116; 21 pwd[0].p_gid=03; 22 strcpy(pwd[0].password,"dddd"); 23 pwd[1].p_uid=2117; 24 pwd[1].p_gid=03; 25 strcpy(pwd[1].password,"bbbb"); 26 pwd[2].p_uid=2118; 27 pwd[2].p_gid=04; 28 strcpy(pwd[2].password,"abcd"); 29 pwd[3].p_uid=2119; 30 pwd[3].p_gid=04; 31 strcpy(pwd[3].password,"cccc"); 32 pwd[4].p_uid=2220; 33 pwd[4].p_gid=05; 34 strcpy(pwd[4].password,"eeee"); 35 36 37 inode=iget(0); 38 inode->di_mode=DIEMPTY; 39 iput(inode); 40 inode=iget(1); 41 inode->di_number=1; 42 inode->di_mode=DEFAULTMODE|DIDIR; 43 inode->di_size=3*(DIRSIZ+2); 44 inode->di_addr[0]=0; 45 strcpy(dir_buf[0].d_name,".."); 46 dir_buf[0].d_ino=1; 47 strcpy(dir_buf[1].d_name,"."); 48 dir_buf[1].d_ino=1; 49 strcpy(dir_buf[2].d_name,"etc"); 50 dir_buf[2].d_ino=2; 51 fseek(fd,DATASTART,SEEK_SET); 52 fwrite(dir_buf,1,3*(DIRSIZ+2),fd); 53 iput(inode); 54 55 inode=iget(2); 56 inode->di_number=1; 57 inode->di_mode=DEFAULTMODE|DIDIR; 58 inode->di_size=3*(DIRSIZ+2); 59 inode->di_addr[0]=1; 60 strcpy(dir_buf[0].d_name,".."); 61 dir_buf[0].d_ino=1; 62 strcpy(dir_buf[1].d_name,"."); 63 dir_buf[1].d_ino=2; 64 strcpy(dir_buf[2].d_name,"password"); 65 dir_buf[2].d_ino=3; 66 fseek(fd,DATASTART+BLOCKSIZ*1,SEEK_SET); 67 fwrite(dir_buf,1,3*(DIRSIZ+2),fd); 68 iput(inode); 69 70 71 inode=iget(3); 72 inode->di_number=1; 73 inode->di_mode=DEFAULTMODE|DIDIR; 74 inode->di_size=BLOCKSIZ; 75 inode->di_addr[0]=2; 76 for(i=5;i<PWDNUM;i++) 77 { 78 pwd[i].p_uid=0; 79 pwd[i].p_gid=0; 80 81 82 strcpy(pwd[i].password," "); 83 } 84 fseek(fd,DATASTART+2*BLOCKSIZ,SEEK_SET); 85 fwrite(pwd,1,BLOCKSIZ,fd); 86 iput(inode); 87 88 filsys.s_isize=DINODEBLK; 89 filsys.s_fsize=FILEBLK; 90 filsys.s_ninode=DINODEBLK*BLOCKSIZ/DINODESIZ-4; 91 filsys.s_nfree=FILEBLK-3; 92 for(i=0;i<NICINOD;i++) 93 { 94 filsys.s_inode[i]=4+i; 95 } 96 97 filsys.s_pinode=0; 98 filsys.s_rinode=NICINOD+4; 99 100 block_buf[NICFREE-1]=FILEBLK+1; 101 for(i=0;i<NICFREE-1;i++) 102 block_buf[NICFREE-2-i]=FILEBLK-i; 103 fseek(fd,DATASTART+BLOCKSIZ*(FILEBLK-NICFREE-1),SEEK_SET); 104 fwrite(block_buf,1,BLOCKSIZ,fd); 105 for(i=FILEBLK-NICFREE-1;i>2;i-=NICFREE) 106 { 107 for(j=0;j<NICFREE;j++) 108 { 109 block_buf[j]=i-j; 110 } 111 block_buf[j]=50; 112 fseek(fd,DATASTART+BLOCKSIZ*(i-1),SEEK_SET); 113 fwrite(block_buf,1,BLOCKSIZ,fd); 114 } 115 j=i+NICFREE; 116 for(i=j;i>2;i--) 117 { 118 filsys.s_free[NICFREE-1+i-j]=i; 119 } 120 filsys.s_pfree=NICFREE-1-j+3; 121 filsys.s_pinode=0; 122 fseek(fd,BLOCKSIZ,SEEK_SET); 123 fwrite(&filsys,1,sizeof(filsys),fd); 124 fseek(fd,BLOCKSIZ,SEEK_SET); 125 fread(&filsys.s_isize,1,sizeof(filsys),fd); 126 }