コードは期待どおりに動作しますが、実行が完了すると 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 ()