segmention fault lstat



  • Hi, ich versuche grad ein kleines Konsolen Porgramm zu schreiben das mir die Verzeichnisstruktur ausgibt, unsortiert in der Reihenfolge wie eben die I-nodes eingetragen sind. Nur leider bekomme ich bei lstat(spielt auch keine Rolle ob ich stat oder lstat verwende) ab der 2. Ebene immer ein Segmention Fault, wenn ich die Rekursion rauslasse scheint aber alles zu funktionieren.

    Die Funktion lstat hat ja nur 2 Parameter. Der Name der Datei wird vorher ordentlich ausgegeben ...

    Also frag ich mich nun wo mein Fehler liegt.

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    
    #include <string.h>
    #include <unistd.h>
    
    int main(int argc, char **argv) {
    
    	if (argc>2) {
    		fprintf(stderr,"Nutzung: %s [start]\n",argv[0]);
    		exit(1);
    	}
    
    	durchsuche(argv[1],0);
    
    	exit(0);
    
    }
    
    int durchsuche(char *ort,int tiefe) {
    
    	DIR *verz;
    	struct dirent *verzinhalt;
    	struct stat *puffer;
    
    	int i;	
    
    	if((verz=opendir(ort))==NULL) {
    		fprintf(stderr,"Fehler beim oeffnen von %s\n",ort);
    		return 1;
    	}
    
    	chdir(ort);
    	while ((verzinhalt=readdir(verz))!=NULL) {
    
    		if (strcmp(verzinhalt->d_name,".")!=0 && strcmp(verzinhalt->d_name,"..")!=0) {
    
    			for (i=0;i<tiefe;i++) {
    				printf("\t");
    			}
    
    			printf("%s\n",verzinhalt->d_name);			
    
    			if (lstat(verzinhalt->d_name,puffer)==-1) 
    			{ 
    
    				fprintf(stderr,"Fehler konnte %s nicht auslesen\n",verzinhalt->d_name);
    				continue;
    			}
    
    			if (S_ISDIR(puffer->st_mode)) {
    
    				durchsuche(verzinhalt->d_name,tiefe+1);
    			}
    
    		}
    
    	}
    
    	if (closedir(verz)==-1) fprintf(stderr,"Fehler beim schließen von %s \n",ort);
    	chdir("..");
    }
    


  • struct stat *puffer; wohin zeigt dieser Pointer?

    Segmentation Faul bedeutet, dass irgend wie versucht wird auf Speicher zuzugreifen, der dem Programm nicht gehört.



  • 1. Das kompiliert nicht, da durchsuche() in main() nicht bekannt ist.
    2. Schau mal im Debugger was passiert, wenn du dein Programm ohne Parameter ausführst.
    3. Schau mal mit Valgrind, was in deinem Fehlerfall passiert.



  • Super schnelle Antworten 😉

    Also ich setz mich gleich mal ran ... ja den Prototypen hab ich oben wohl vergessen, der Fehler, der entstehen sollte wenn ich das Programm ohne Parameter starte ist mir auch bekannt(ich hab bisschen was rausgenommen, um das Problem besser schildern zu koennen, dabei wohl neue Fehler reingebaut ;-)), gut, wie auch immer ich versuch jetzt mal das Problem zu lösen



  • Nun gut ich hab den Fehler jetzt auch gefunden, hier mal der Korriegierte Quelltext

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    
    #include <string.h>
    #include <unistd.h>
    
    int durchsuche(char *ort,int tiefe);
    
    int main(int argc, char **argv) {
    
    	if (argc>2) {
    		fprintf(stderr,"Nutzung: %s [start]\n",argv[0]);
    		exit(1);
    	}
    
    	if (argc==1) durchsuche("/",0);
    	else durchsuche(argv[1],0);
    
    	exit(0);
    
    }
    
    int durchsuche(char *ort,int tiefe) {
    
    	DIR *verz;
    	struct dirent *verzinhalt;
    	struct stat *puffer;
    
    	puffer=(struct stat*)malloc(sizeof(struct stat));
    
    	int i;	
    
    	if((verz=opendir(ort))==NULL) {
    		fprintf(stderr,"Fehler beim oeffnen von %s\n",ort);
    		return 1;
    	}
    
    	chdir(ort);
    	while ((verzinhalt=readdir(verz))!=NULL) {
    
    		if (strcmp(verzinhalt->d_name,".")!=0 && strcmp(verzinhalt->d_name,"..")!=0) {
    
    			for (i=0;i<tiefe;i++) {
    				printf("\t");
    			}
    
    			printf("%s\n",verzinhalt->d_name);			
    
    			if (lstat(verzinhalt->d_name,puffer)==-1) 
    			{ 
    
    				fprintf(stderr,"Fehler konnte %s nicht auslesen\n",verzinhalt->d_name);
    				continue;
    			}
    
    			if (S_ISDIR(puffer->st_mode)) {
    
    				durchsuche(verzinhalt->d_name,tiefe+1);
    			}
    
    		}
    
    	}
    
    	if (closedir(verz)==-1) fprintf(stderr,"Fehler beim schließen von %s \n",ort);
    	chdir("..");
    }
    

    Was ich überhaupt nicht verstehen mag warum das beim ersten Nutzen der Funktion problemlos klappt ... das mit den Pointern scheint mich wohl noch ein wenig zu verwirren, scheinbar wird in der Funktion lstat der Speicher nicht zur verfügung gestellt, sondern einfach versucht die Struktur mit Daten zu füllen, währen Funktionen mit einem Pointer als Rückgabetyp den Speicher selbst bereitstellen ... so oder ähnlich stell ich mir das jetzt mal vor



  • afaik musst du für lstat schon selbst den speicher bereitstellen.
    also ändere mal die deklaration um in

    struct stat puffer;
    

    und der aufruf sieht dann entsprechend so aus:

    lstat(verzinhalt->d_name,&puffer)==-1
    

    dann sollte auf jeden fall der segfault weg sein


Anmelden zum Antworten