Segmentation Fault su fclose()

Area di discussione libera.

Moderatore: Staff

Regole del forum
1) Rispettare le idee altrui.
2) Evitare le offese dirette.
3) Leggere attentamente le risposte ricevute
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Segmentation Fault su fclose()

Messaggio da Blizzard »

Ciao ragà vi posto l'ultima funzione della shell ovvero quella che si occupa di verificare in base ad un file se esiste un programma associato nel file di configurazione

Codice: Seleziona tutto

//This function take the filename as parameter
//get his extension and find in the config file 
//the relative program (if exist).
//This function returns the string of the program if exists
//otherwise returns NULL
char* FindFileAssociation(char *line)
{
	FILE *stream=NULL;
	char conffile[2048];
	char ext[2048];
	char *home=NULL;
	char *result=NULL;
	char *p=NULL;
	char *l=NULL,*j=NULL, *k=NULL;;
	char *temp=NULL;
	int n=2047;
	int i=0;
	
	if(!line)
	{
		fprintf(stderr,"ERROR!!! line parameter is NULL\n");
		fprintf(stderr,"This error could not happen!!! what's wrong!!! HEEEEEEELP!!!\n");
		fprintf(stderr,"Error in FindFileAssociation in [association.c]\n");
		return NULL;
	}
	
	//allocating the string that contains the result
	result=malloc(2048);
	if(!result)
	{
		fprintf(stderr,"Could not allocate the memory for the result string\n");
		fprintf(stderr,"Error in FindFileAssociation in [association.c]\n");
		return NULL;
	}
	//Zeroing out the structure
	memset(result,0,2048);
	
	//searching the extension .something
	//we simply search the first dot in the string line
	p=line;
	while(*p!='.')
	{
		if(p=='\0')
		{
			fprintf(stderr,"There is no extension in the filename!!!\n");
			fprintf(stderr,"Could not continue! Error in FindFileAssociation in [association.c]\n");
			free(result);
			result=NULL;
			return NULL;
		}
		p++;
	}
	p++; //step to the extensions after the dot
	
	//Opening the config file
	home=getenv("HOME");
	if(!home)
	{
		fprintf(stderr,"Could not take the home directory!\n");
		fprintf(stderr,"Error in FindFileAssociation [association.c]\n");
		return NULL;
	}
	memset(conffile,0,2048);
	strcpy(conffile,home);
	strcat(conffile,"/.bohshell_conf");
		
	stream=fopen(conffile,"rt");
	
	if(!stream)
	{
		fprintf(stderr,"There is no config file [~/.bohshell_conf]\n");
		fprintf(stderr,"Could not continue! Error in FindFileAssociation in [association.c]\n");
		free(result);
		result=NULL;
		return NULL;
	}
	
	
	//finding the first tag @start bohsh config
	while(1)
	{
		//free(temp);
		//temp=NULL;
		if(getline(&temp,&n,stream)==-1)
		{
			fprintf(stderr,"Warning!reached the end of configuration file\n");
			fprintf(stderr,"whithout finding tags\n");
			fprintf(stderr,"No association file found\n");
			fclose(stream);
			free(result);
			result=NULL;
			return NULL;
		}
		l=temp;
		
		//space removal
		while(*l==' ')l++;
		
		if(*l=='@')
		{
		
		
			//verifying
			j=l;
			while(*j!='\0')
			{
				if(*j=='\n')
				{
					*j='\0';
					break;
				}
				j++;
			}
			
			if(strcmp(l,"@start association\0")!=0)
			{
				printf("%s\n",l);
				fprintf(stderr,"Warning!error in the parsing of configuration file\n");
				fprintf(stderr,"could not find @start association config\n");
				fprintf(stderr,"No association file found\n");
			}	
			else
			{
				printf("HERE\n");
				break;
			}	
		}
		memset(temp,0,2048);
	}
	
	
	
	
	//finding the program association
	memset(temp,0,2048);
	while(1)
	{
	printf("HERE1\n");
		if(getline(&temp,&n,stream)==-1)
		{
			fprintf(stderr,"Warning!reached the end of configuration file\n");
			fprintf(stderr,"whithout finding tags\n");
			fprintf(stderr,"No association file found\n");
			fclose(stream);
			free(result);
			result=NULL;
			return NULL;
		}
		
		
		l=temp;
		
		if(strcmp(p,"@end association\0")==0)
		{
			fprintf(stderr,"Warning!reached the end of configuration tag\n");
			fprintf(stderr,"whithout finding associations\n");
			fprintf(stderr,"No association file found\n");
			fclose(stream);
			free(result);
			result=NULL;
			return NULL;
		}
		
		
		while(*l==' ') l++;
		
		//copyng the extension
		memset(ext,0,2048);
		for(i=0; i<2047; i++)
		{
			//we exit if we reach the end of the config string
			//because we have no program associated with the extension
			if(*l=='\0' || *l=='\n')
			{
				fprintf(stderr,"Error! Bad config option\n");
				fprintf(stderr,"in the association settings\n");
				fprintf(stderr,"No program associated to an extension\n");
				fclose(stream);
				free(result);
				result=NULL;
				return NULL;
			}
			
			//we find the estension!
			//we can exit by this for to control if
			//the extension is the one we are searching for
			if(*l==' ' || *l=='|')
			{
				//space and '|' removal
				while(*l==' ' || *l=='|') 
				{
					l++;
				}
				break;
			}
			
			ext[i]=*l;
			l++;
		}
		ext[i+1]='\0';
		
		
		i=0;
		i=strcmp(p,ext);
		if(i==0)
		{
		
			//return the program name with parameters
			//associated to the extension
			strcpy(result,l);
			printf("FOFO\n");
			//fclose(stream);
			return result;
		}
		
	}//end while find the program association
	
}
In pratica nell'ultimo if vedete prima del return result la chiamata di funzione fclose commentata.
Se la decommento e di conseguenza da bravo chiudo il file il programma mi esplode!
Secondo voi perchè?????

ciao
Gio

Avatar utente
lamarozzo
Linux 3.x
Linux 3.x
Messaggi: 732
Iscritto il: gio 14 lug 2005, 0:00
Desktop: xfce
Distribuzione: archlinux
Località: Roma

Messaggio da lamarozzo »

La mia è solo una risposta al volo.

fclose() può esplodere se chiudi uno stream già chiuso. Non è magari questo il tuo caso? Ho visto che ci sono un po' di fclose() disseminati in giro.

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Messaggio da Blizzard »

ciao!
mi hai messo la pulce nell'orecchio e ho controllato!
ogni fclose è seguita da un opportuno return poichè questi casi sono quelli che per un modo o per un altro hanno fallito l'esecuzione....

mah! spero di risolvere... o quanto meno di capire!

grazie
Giovanni

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Messaggio da Mario Vanoni »

if (fclose(stream) == 0)
return(result);
else
return(fprintf(stderr, "... quello che serve a capire ..."));

Mario Vanoni

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Messaggio da Mario Vanoni »

Domanda:

il programma e` solo per C99 od anche per C89?

Se si`, attento ai commenti // invece di /* ... */
non compilabili in molti ambienti.

Mario Vanoni

Avatar utente
lamarozzo
Linux 3.x
Linux 3.x
Messaggi: 732
Iscritto il: gio 14 lug 2005, 0:00
Desktop: xfce
Distribuzione: archlinux
Località: Roma

Messaggio da lamarozzo »

il segmentation fault lo becchi anche se provi a chiudere uno stream che non hai aperto.

Ad esempio il seguente codice esplode

Codice: Seleziona tutto

FILE *stream=NULL;
fclose(stream);
Magari controlla che il tuo codice non ricada anche in questa casistica.

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Messaggio da Blizzard »

ciao!
if (fclose(stream) == 0)
return(result);
else
return(fprintf(stderr, "... quello che serve a capire ..."));
Non servirebbe a nulla in quanto la fclose non ritorna nulla! e proprio lei che genera l'errore in quanto se metto qualche printf dopo non arriva a stamparla.
il programma e` solo per C99 od anche per C89?

Se si`, attento ai commenti // invece di /* ... */
non compilabili in molti ambienti.
Ciao! ho progettato la shell per il C89 in tutto fuor che nei commenti!
magari realizzerò un programma per convertire i commenti in futuro e renderlo aderente anche perchè non mi piace proprio il vecchio sistema dei commenti.
Non me ne sono curato perchè fondamentalmente sono quasi 10 anni che esiste il "nuovo standard" e spero che sia più utilizzato di 3/4 anni fa
il segmentation fault lo becchi anche se provi a chiudere uno stream che non hai aperto.

Ad esempio il seguente codice esplode

Codice:

FILE *stream=NULL;
fclose(stream);
Anche questo è improbabile, poichè se non è possibile aprire il file la funzione ritorna... anche se non è possibile lavorarci esce prima di svolgere qualsiasi operazione.
Se arriva là con successo significa che il file c'è, lo apre e lo legge.

ciao
Gio

bloodlust
Linux 3.x
Linux 3.x
Messaggi: 523
Iscritto il: mar 14 feb 2006, 12:02
Slackware: -1
Località: it_IT

Messaggio da bloodlust »

Blizzard ha scritto:
if (fclose(stream) == 0)
return(result);
else
return(fprintf(stderr, "... quello che serve a capire ..."));
Non servirebbe a nulla in quanto la fclose non ritorna nulla! e proprio lei che genera l'errore in quanto se metto qualche printf dopo non arriva a stamparla.
infatti devi testare la validità del file pointer prima di ogni chiamata a fclose().

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Messaggio da Blizzard »

ciao!
infatti devi testare la validità del file pointer prima di ogni chiamata a fclose().
io non la testavo perchè se il codice arrivava la il puntatore doveva essere per forza valido.... altrimenti esplodeva prima.
Comunque... solita pulce nell'orecchio e cambio il codice così

Codice: Seleziona tutto

if(i==0)
		{
		
			//return the program name with parameters
			//associated to the extension
			strcpy(result,l);
			printf("FOFO\n");
			if(stream) fclose(stream);
			return result;
		}
Purtroppo il risultato non cambia, perchè il puntatore risulta valido ma esplode lo stesso alla fclose.

ciao
Gio

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Messaggio da targzeta »

Ma un debugger lo usi? Altrimenti è difficile venirne a capo, specialmente quando il codice si farà più esteso.

comunque, prova a far sì che il tuo programma si fermi prima, prova, cioé, a modificare il file di configurazione in modo da testare le altre fclose().

Spina

P.S. ma quel "rt" che vuol dire nella fopen?
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
absinthe
Iper Master
Iper Master
Messaggi: 2354
Iscritto il: dom 15 mag 2005, 0:00
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze
Località: Prato
Contatta:

Messaggio da absinthe »

spina ha scritto:Ma un debugger lo usi? Altrimenti è difficile venirne a capo, specialmente quando il codice si farà più esteso.

comunque, prova a far sì che il tuo programma si fermi prima, prova, cioé, a modificare il file di configurazione in modo da testare le altre fclose().

Spina

P.S. ma quel "rt" che vuol dire nella fopen?
r=read, t=text mode

in effetti se si da un occhio a http://www.opengroup.org/onlinepubs/000 ... fopen.html
si nota che tale modalità non esiste... io la uso da una vita sotto dos/windows. blizzard: non è che hai fatto casino?!

M

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Messaggio da Blizzard »

ciao Abshinte,

dici che il prog mi esplode per quella modalità di apertura???
Cavolo... bill mi perseguita ancora :D

Comunque provo e vi faccio sapere.

Ciao
Gio

Avatar utente
lamarozzo
Linux 3.x
Linux 3.x
Messaggi: 732
Iscritto il: gio 14 lug 2005, 0:00
Desktop: xfce
Distribuzione: archlinux
Località: Roma

Messaggio da lamarozzo »

Mi sembra strano che fopen non restituisca NULL se si apre un file con una modalità sconosciuta. Per sicurezza prova a controllare cosa dice la variabile errno
(http://science.unitn.it/~fiorella/guidac/guidac092.html) dopo la chiamata a fopen.

Comunque la modalità "rt" è la prima volta che la sento, stasera provo a vedere se sul K&R è prevista.

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Messaggio da Blizzard »

ciao

ho corretto anche il modo di apertura del file ma non cambia le cose...

comunque vedrò di fare il debugging...
in ogni caso domani metto online sul CVS la beta del sistema di associazione file/programma... perchè comunque devo fare un paio di modifiche.

ciao
Gio

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Messaggio da Blizzard »

Ciao,
comunque, prova a far sì che il tuo programma si fermi prima, prova, cioé, a modificare il file di configurazione in modo da testare le altre fclose().
Ho provato e ad ogni fclose il programma esplode... o meglio non esplode praticamente sempre ma solo se la fclose è all'interno del blocco:

Codice: Seleziona tutto

if(getline(&temp,&n,stream)==-1)
{
....
....
..
}
in altre parti invece mi chiude tranquillamente il file! :? :? :? :? :? :? :?

vi salta in mente niente????
ciao
Gio

Rispondi