|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
[C] Segmentation fault
Ciao.
Potreste aiutarmi a scovare l'errore in queste due (o in una di queste due funzioni) ? La funzione intepret_file legge da un file una linea di testo che corrisponde ad un comando Unix e sostituisce gli argomenti $i con gli argomenti passati a linea di comando. La funzione parse invece esegue tutte le operazioni di shell expansion. Ho provato con un file di prova contenente tre linee: ls $1 $4 ps $3 uname $2 dove $1="-l" $2="*.c" $3="aux" $4="-r". Il problema avviene quando va a leggere la terza linea e chiama la funzione parse. Verso la fine nel while(cnt<pwordexp.we_wordc) va in segmentation fault sull'istruzione "args[i]=(char *)calloc(strlen(pwordexp.we_wordv[i-2])+1,sizeof(char));" (nonostante args[i]=NULL). Non riesco a capire perché. Questo è il codice delle due funzioni: interpret_file.c Codice:
#include "functions.h"
void interpret_file(int numargs,char **args){
int fdin,i,j,status,offset;
pid_t pid;
ssize_t nread;
char *buf=(char *)malloc(sizeof(char)*MAX_CMD_LEN);
if((fdin=open(args[1],O_RDONLY)) == -1){
if(errno==EINTR){
if(buf!=NULL){
free(buf);
buf=NULL;
}
close(fdin);
exit(OK);
}
else{
perror("open error");
if(buf!=NULL){
free(buf);
buf=NULL;
}
close(fdin);
exit(OPEN_ERR);
}
}
while((nread=read(fdin,buf,MAX_CMD_LEN)) > 0 || nread == -1){
char **passargs=(char **)calloc(MAX_ARGS,sizeof(char *));
if(nread == -1){
if(errno==EINTR){
if(buf!=NULL){
free(buf);
buf=NULL;
}
close(fdin);
exit(OK);
}
else{
perror("read error");
if(buf!=NULL){
free(buf);
buf=NULL;
}
close(fdin);
exit(OPEN_ERR);
}
}
j=0;
offset=0;
char *pbuf=buf;
if(nread < MAX_CMD_LEN){
if(errno==EINTR){
if(buf!=NULL){
free(buf);
buf=NULL;
}
close(fdin);
exit(OK);
}
else{
perror("read error");
if(buf!=NULL){
free(buf);
buf=NULL;
}
close(fdin);
exit(READ_ERR);
}
}
while(*pbuf != '$'){
++pbuf;
++offset;
}
passargs[j]=(char *)calloc(offset,sizeof(char));
strncpy(passargs[j],buf,offset-1);
passargs[offset]='\0';
++j;
for( ; *pbuf=='$'; pbuf+=2){
++pbuf;
switch(*pbuf){
case '1':
i=2;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '2':
i=3;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '3':
i=4;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '4':
i=5;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '5':
i=6;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '6':
i=7;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '7':
i=8;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '8':
i=9;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
case '9':
i=10;
passargs[j]=(char *)calloc(strlen(args[i]),sizeof(char));
strcpy(passargs[j],args[i]);
++j;
break;
default:
printf("Too many arguments\n");
if(buf!=NULL){
free(buf);
buf=NULL;
}
if(passargs!=NULL){
free(passargs);
passargs=NULL;
}
exit(ERR_GEN);
}
}
parse(NULL,passargs);
if((pid=fork()) < 0){
perror("fork error");
if(passargs!=NULL){
free(passargs);
passargs=NULL;
}
if(buf!=NULL){
free(buf);
buf=NULL;
}
exit(FORK_ERR);
}
if(pid == 0){
execvp(passargs[0],passargs);
perror("exec failed");
if(passargs!=NULL){
free(passargs);
passargs=NULL;
}
if(buf!=NULL){
free(buf);
buf=NULL;
}
exit(EXEC_ERR);
}
if(pid > 0){
if (waitpid(pid,&status,0) == -1){
if(errno!=EINTR){
perror("waitpid error");
if(passargs!=NULL){
free(passargs);
passargs=NULL;
}
if(buf!=NULL){
free(buf);
buf=NULL;
}
exit(WAIT_ERR);
}
else{
kill(pid,SIGTERM);
do{
if (waitpid(pid,&status,0) != -1)
break;
}while(errno==EINTR);
}
}
}
if(passargs!=NULL){
free(passargs);
passargs=NULL;
}
}
close(fdin);
if(buf!=NULL){
free(buf);
buf=NULL;
}
}
Codice:
#include "functions.h"
void parse(char *name, char **args){
int i=0,j=0,cnt=0;
char *s;
if(args[i] == NULL)
args[i]=(char *)malloc(sizeof(char)*COMM_LENGTH+1);
if (strtok(name," ") != NULL){
strcpy(args[i],name);
++i;
}
while((s=strtok(NULL," ")) != NULL){
args[i]=(char *)malloc(sizeof(char)*strlen(s)+1);
sprintf(args[i],"%s",s);
++i;
}
if(args[i] == NULL)
args[i]=NULL;
if(s!=NULL){
free(s);
s=NULL;
}
int ret;
i=1;
while(args[i] != NULL){
if(*args[i] == '-'){
++i;
++j;
continue;
}
if ((ret=wordexp(args[i],&pwordexp,0)) == 0)
++i;
else{
printf("wordexp error");
if(args!=NULL){
free(args);
args=NULL;
}
exit(WRDEXP_ERR);
}
}
if(j>0){
i=j+1;
while(cnt<pwordexp.we_wordc){
if(args[i]==NULL)
args[i]=(char *)calloc(strlen(pwordexp.we_wordv[i-2])+1,sizeof(char));
strcpy(args[i],pwordexp.we_wordv[i-2]);
++cnt;
++i;
}
}
args[i]=NULL;
wordfree(&pwordexp);
}
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ho risolto. Praticamente era la variabile wordexp che non veniva inizializzata per quel comando nella funzione parse e naturalmente non riusciva ad allocare memoria. Grazie lo stesso.
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
quando succedono queste cose perché non fai una bella strace (da quel che vedo al volo sei su linux, o sbaglio ? )
Codice:
strace -f -F -s 1024 -o file.trace ./<nome prog>
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Eh infatti cercavo un utility che mi facilitasse il compito. Grazie, ne terrò conto per il prossimo.
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
l'alternativa é printf fino alla nausea
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 06:09.



















