0

コードは期待どおりに動作しますが、実行が完了すると glibc エラーが発生します。省略の仕方を教えてください。

#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 fclose@@GLIBC_2.2.5 () from /lib64/libc.so.6
#6  0x0000000000400c18 in main ()
4

1 に答える 1

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() が 2 回呼び出されるなど、他にも問題があります。それがあなたの問題の根本です。

注: 本当にwhile (1)バッチ モードが必要ですか?

于 2013-09-28T22:28:54.040 に答える