Question

My code works as expected but when it is done executing I receive the glibc error. Can you please guide me how to omit it?

#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;

}

Here's the output I received accompanied by the error:

./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)

Also here's a little of the information extracted by 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 ()
Was it helpful?

Solution

   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.

Maybe new_argv[2] should be new_argv[3]. Can't hurt anyway. That may not be the only problem though.

Also,

     fclose(bfd);

Can be called with an uninitialized bfd. See the logic in your main().

There are other issues too like fclose() being called twice. That is the root of your issue.

Note: Do you really want the while (1) in batch mode?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top