2013-09-28 54 views
0

我的代碼按預期工作,但執行完成後,我收到glibc錯誤。你能指導我如何省略它嗎?*** glibc檢測到*** ./shell:雙重空閒或損壞(頂部)---中止(核心轉儲)

#include <stdio.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <assert.h> 
#include <signal.h> //for kill 
#include <fcntl.h> 


int py_flag=0; 
void execute(char **argv) 
{ 

    int status; 
    int pid = fork(); 
    if (pid <0) //fork error has happened 
    { 
     perror("Can't fork a child process\n"); 
     exit(EXIT_FAILURE); 
    } 
    if (pid==0) //It's the child process and can run his task 
    { 

     if (py_flag==1) 
     { 
      char *new_argv[2]; 
      //char *new_argv[3]; 
      new_argv[0]="/usr/bin/python"; 
      new_argv[1]=argv[0]; 
      new_argv[2]=0; 
      execvp(new_argv[0],new_argv); 
     } 
     else 
     { 

    execvp(argv[0],argv); 
     perror("error"); 
     } 
    } 
    else //pid>0 it's the parent and should wait for the child 
    { 
     int status; 
     // int wc = wait(&status); 
     // assert(wc != -1); 

     //while(wait(&status)!=pid) 
     // ; 
     wait(NULL); 
    } 


} 

int main (int argc, char **argv) 

{ 
    FILE *bfd=NULL; //batch file descriptor 
    char cwd[100]; 
    int batch_mode; 
    char input[512]; 
    char *args[512]; 
    char **next = args; 
    char *temp; 
    getcwd(cwd,sizeof(cwd)); 
    if (argv[1]!=0) 
     { 
     batch_mode=1; 
     if((bfd = fopen(argv[1], "r")) == NULL) 
      { 
        printf("Error Opening File.\n"); 
        //exit(1); 
      } 
     else 
      printf("batch file name is %s \n",argv[1]); 
     } 
    while (1) 
    { 


     chdir(cwd); 
     if (batch_mode) 
     { 
      while(fgets(input, sizeof(input), bfd) != NULL) 
      { 

       write(STDOUT_FILENO,input, strlen(input)); 
       input[strlen(input) - 1] = 0; 
       temp = strtok(input, " "); 
       while(temp != NULL) 
        { 
        *next++ = temp; 
        temp = strtok(NULL, " "); 

        } 
       *next = NULL; 
       next=args; 
       execute(args); 

      } 
      printf(" bfd is %p \n",bfd); 
      fclose(bfd); 
     } 
     else 
     { 
      printf("mysh> "); 
      fgets(input,512,stdin); 
      input[strlen(input) - 1] = 0; 
      temp = strtok(input, " "); 
      while(temp != NULL) 
      { 
        //printf("%s\n", temp); 
        *next++ = temp; 
        temp = strtok(NULL, " "); 

       }  
      *next = NULL; 
      next=args; 

      if (strstr(args[0],".py") !=NULL) 
      { 
       py_flag=1; 
       printf("I am a python program\n"); 
      } 
      if (strcmp(args[0], "exit")==0) 
       exit(0); 
      if (strcmp(args[0], "cd")==0) 
      { 
       printf("argv[1] is %s \n", args[1]); 
       if ((!args[1]) || (strcmp(args[1],"~")==0)) 
        { 
        chdir(getenv("HOME")); 
        getcwd(cwd,sizeof(cwd)); 
        } 
       else 
        { 
        chdir(args[1]); 
        getcwd(cwd,sizeof(cwd)); 
        } 
      } 
      else 
      { 
       execute(args); 
      } 

      } 


    } 

    return 0; 

} 

這是我收到了進行錯誤輸出:

./shell myBatchFile 
batch file name is myBatchFile 
pwd 
/afs/cs.wisc.edu/u/j/a/jalal/fall2013/shell 

bfd is 0x1d83010 
bfd is 0x1d83010 
*** glibc detected *** ./shell: double free or corruption (top): 0x0000000001d83010 *** 
======= Backtrace: ========= 
/lib64/libc.so.6[0x3c64876126] 
/lib64/libc.so.6[0x3c64878c53] 
/lib64/libc.so.6(fclose+0x14d)[0x3c6486678d] 
./shell[0x400c39] 
/lib64/libc.so.6(__libc_start_main+0xfd)[0x3c6481ecdd] 
./shell[0x400919] 
======= Memory map: ======== 
00400000-00402000 r-xp 00000000 00:12 1049079136       /afs/cs.wisc.edu/u/j/a/jalal/fall2013/shell/shell 
00601000-00602000 rw-p 00001000 00:12 1049079136       /afs/cs.wisc.edu/u/j/a/jalal/fall2013/shell/shell 
01d83000-01da4000 rw-p 00000000 00:00 0         [heap] 
3c64400000-3c64420000 r-xp 00000000 08:02 393388       /lib64/ld-2.12.so 
3c6461f000-3c64620000 r--p 0001f000 08:02 393388       /lib64/ld-2.12.so 
3c64620000-3c64621000 rw-p 00020000 08:02 393388       /lib64/ld-2.12.so 
3c64621000-3c64622000 rw-p 00000000 00:00 0 
3c64800000-3c6498a000 r-xp 00000000 08:02 394819       /lib64/libc-2.12.so 
3c6498a000-3c64b89000 ---p 0018a000 08:02 394819       /lib64/libc-2.12.so 
3c64b89000-3c64b8d000 r--p 00189000 08:02 394819       /lib64/libc-2.12.so 
3c64b8d000-3c64b8e000 rw-p 0018d000 08:02 394819       /lib64/libc-2.12.so 
3c64b8e000-3c64b93000 rw-p 00000000 00:00 0 
3c6e800000-3c6e816000 r-xp 00000000 08:02 394824       /lib64/libgcc_s-4.4.7-20120601.so.1 
3c6e816000-3c6ea15000 ---p 00016000 08:02 394824       /lib64/libgcc_s-4.4.7-20120601.so.1 
3c6ea15000-3c6ea16000 rw-p 00015000 08:02 394824       /lib64/libgcc_s-4.4.7-20120601.so.1 
7f8f55655000-7f8f55658000 rw-p 00000000 00:00 0 
7f8f55679000-7f8f5567c000 rw-p 00000000 00:00 0 
7ffff4da9000-7ffff4dbf000 rw-p 00000000 00:00 0       [stack] 
7ffff4ded000-7ffff4dee000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
Aborted (core dumped) 

而且這裏有一個小的被GDB提取的信息:

Program received signal SIGABRT, Aborted. 
0x0000003c648328e5 in raise() from /lib64/libc.so.6 
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6_4.4.x86_64 libgcc-4.4.7-3.el6.x86_64 
(gdb) bt 
#0 0x0000003c648328e5 in raise() from /lib64/libc.so.6 
#1 0x0000003c648340c5 in abort() from /lib64/libc.so.6 
#2 0x0000003c648707f7 in __libc_message() from /lib64/libc.so.6 
#3 0x0000003c64876126 in malloc_printerr() from /lib64/libc.so.6 
#4 0x0000003c64878c53 in _int_free() from /lib64/libc.so.6 
#5 0x0000003c6486678d in [email protected]@GLIBC_2.2.5() from /lib64/libc.so.6 
#6 0x0000000000400c18 in main() 

回答

0
char *new_argv[2]; 
    new_argv[0]="/usr/bin/python"; 
    new_argv[1]=argv[0]; 
    new_argv[2]=0; // <-- this reference is out of bounds. 

也許new_argv[2]應該new_argv[3] 。無論如何不能傷害。 雖然這可能不是唯一的問題。

此外,

 fclose(bfd); 

可以用未初始化BFD調用。看看你的main()中的邏輯。

還有其他問題,如fclose()被調用兩次。這是你問題的根源 。

注意:你真的想在批處理模式下使用while (1)嗎?

+0

我甚至沒有在shell模式下運行我的程序,我甚至沒有餵它的Python程序。它正在以批處理模式運行(我正在給包含我的命令的batchFile)。所以錯誤不應該來自代碼的那部分。順便說一下這部分代碼在shell模式下工作,我不明白爲什麼你告訴我它應該是new_argv [3]? –

+1

將bfd初始化爲0,然後在關閉之前將其打印出來。看看是不是0. –

+0

我編輯了我的代碼和它顯示的結果。你可以看看嗎?正如你看到我已經打印bfd,但它打印兩次!你知道爲什麼嗎?我是否也正確地初始化它? 'bfd是0x1d83010 bfd是0x1d83010' –

相關問題