Fehlermeldung 1798 Segmentation fault



  • Hi,
    ich versuche momentan einen Ultraschallsensor SRF05 mit einem Foxboard G20 (Gentoo Linux) zu btreiben. Da ich leider noch nicht viel Ahnung von C Programmieren habe (vor allen nicht mit Dateioperationen) finde ich einfach nicht mein Fehler.

    Folgender Code:

    /************************************************
    
    Programm für den vorderen Ulstraschallsensor
    
    *************************************************/
    #include <stdio.h>
    
    /*Funktion zum stoppen der Motoren*/
    int stop()
    {
        FILE *fp1;
        FILE *fp2;
    
         fp1= fopen( "/sys/class/gpio/gpio59/value","w");  
         fp2= fopen( "/sys/class/gpio/gpio60/value","w");
    
         fprintf(fp1,"1");
         fprintf(fp2,"1");
    
         fclose(fp1);  
         fclose(fp2); 
    
        ausloesen();
    
        return 0;
    }
    
    /*Funktion zum Verarbeiten des vom Sensor zurück kommenden Signals*/
    int signalverarbeiten(int wiederholung)
    {
        FILE *fp;
        int erg=0;
    
        fp = fopen( "/sys/class/gpio/gpio85/value","r");
    
            fscanf(fp,"%d",&erg);
            fclose(fp);
    
            if(!fp)                                                                     
            {                                                                         
      printf("Fehler beim oeffnen der value Datei (Sensor  Vorne)\n");                  
            }
    
        switch (wiederholung)
               {
                case 1:
    
                      if(erg == 1)
                      {
                             usleep(55);
                             signalverarbeiten(2);
    
                      }
                      if(erg == 0)
                      {
                             ausloesen();
    
                      }
                      else
                      {
                          printf("\nFehler in der value Datei beim Auswerten des Signals\n");
                      }
                break;
                case 2:
    
                     if(erg == 1)
                      {
                             usleep(58);
                             signalverarbeiten(3);
    
                      }
                      if(erg == 0)
                      {
                             ausloesen();
    
                      }
                      else
                      {
                          printf("\nFehler in der value Datei beim Auswerten des Signals\n");
                      }     
                break;
                case 3:
                     if(erg == 1)
                      {
                             stop();
    
                      }
                      if(erg == 0)
                      {
                          ausloesen();   
    
                      }
                      else
                      {
                          printf("\nFehler in der value Datei beim Auswerten des Signals\n");
                      }
                break;
                default:
    
                       printf("\nFehler beim Vearbeiten des Signals vom SRF05\n");
    
               }
    
        return 0;
    }
    
    /*Funktion zum auslösen des Sensors*/
    int ausloesen()
    {
        FILE *fp;
    
             fp = fopen( "/sys/class/gpio/gpio85/direction","w");             
             fprintf(fp,"out");                                                
             fclose(fp);
    
            if(!fp)                                                                     
            {                                                                         
                   printf("Fehler beim oeffnen der direction Datei (Sensor)\n");                  
            }                                                    
    
            fp = fopen( "/sys/class/gpio/gpio85/value","w");                                                                         
    
            if(!fp)                                                                     
            {                                                                         
                   printf("Fehler beim oeffnen der value Datei (Sensor)\n");                  
            }                                                                         
    
            fprintf(fp,"1");                                                    
            fclose(fp);                                                           
    
            usleep(10);                                                            
    
            fp = fopen( "/sys/class/gpio/gpio85/value","w");                    
    
            if(!fp)                                                                     
            {                                                                           
                   printf("Fehler beim oeffnen der value Datei (Sensor)\n");                       
            }
    
            fprintf(fp,"0");                                                      
            fclose(fp);                                                           
    
            fp = fopen( "/sys/class/gpio/gpio85/direction","w");                   
            fprintf(fp,"in");                                                     
            fclose(fp);
    
            if(!fp)                                                                     
            {                                                                         
                   printf("Fehler beim oeffnen der direction Datei (Sensor)\n");                  
            }                                                            
    
            signalverarbeiten(1);
    
     return 0;   
    }
    
    /*Main Funktion*/
    int main()
    {
        ausloesen();
    
       return 0; 
    }
    

    Wenn ich die mit den gcc Compiler compilierte Datei ausführen möchte, kommt folgende Fehlermeldung:

    "1798 Segment fault"

    Natürlich habe ich diese Meldung schon bei [gg] eingegeben, habe aber leider keine Lösung gefunden.

    Ich freue mich über jede Hilfe.

    Pascal



  • Hau ganz viele Debug-Ausgaben rein, damit Du erstmal rausfindest, in welcher Zeile das Böse passiert.

    fp = fopen( "/sys/class/gpio/gpio85/value","r"); 
    
            fscanf(fp,"%d",&erg); 
            fclose(fp); 
    
            if(!fp)                                                                     
            {                                                                         
      printf("Fehler beim oeffnen der value Datei (Sensor  Vorne)\n");                   
            }
    

    wird zu

    printf("test0\n");        
            fp = fopen( "/sys/class/gpio/gpio85/value","r"); 
    printf("test1\n");        
            fscanf(fp,"%d",&erg); 
    printf("test2\n");        
            fclose(fp); 
    printf("test4\n");        
    
            if(!fp)                                                                     
            {                                                                         
    printf("test5\n");        
      printf("Fehler beim oeffnen der value Datei (Sensor  Vorne)\n");                   
    printf("test6\n");        
            } 
    printf("test7\n");
    

    und so weiter...



  • Hi volkard,

    ich habe deine schöne Fehlersuche durchgeführt 🙂
    Ich kam auf 106 mal printf(); 😉

    Und komischer Weise kam diese Fehlermeldung nicht mehr und das Programm rasselte so durch. Als ob mich das Board ärgern wolle :p

    Also weiß ich nicht wodran es lag. Trotzdem vielen Dank für den Tipp. Wenn das nächste mal ein Programm nicht durchläuft mach ich es direkt so 🕶

    Allerdings wahr die gwünschte Funktion noch nicht gegeben. Aber das gehört glaube ich nicht hier hin!

    Also, danke nochmal für den Tipp

    Grüße aus Dortmund

    Pascal



  • Machmal stürzt so ein Ding ab, ohne dass noch der Ausgabepuffer geleert wird. Statt printf() besser eine eigene Funktion nehmen:

    void log(char *s)
    {
        fputs(s, stderr);
        fflush(stderr);
    }
    

    🙂



  • Danke mngbd,

    ich habe einfach vor jeden fclose(...) ein fflush(...) gesetzt! Jetzt stürzt das Board nnicht mehr so schnell ab. D.h beim ersten ausprobieren hat es bestimmt 5min gehalten. Dann ist es allerdings wieder abgestürzt.

    Aber das fflush hat mir auf jeden Fall geholfen.

    Ich kann mir vorstellen, das mein Board mit z.B. usleep(10) nicht klarkommt. Das ist ja eine echt kurze Zeit.

    Kann mir vielleicht jemand sagen, wie schnell so ein C Programm abgearbeitet wird. Ich meine von Befehl zu Befehl brauch der Rechner ja auch eine Zeit. (Vielleicht ns).

    Leider ist die Funktion immer noch viel zu ungenau, da werde ich mich mal an den Support von den SRF05 wenden müssen.

    Gruß aus D

    Pascal



  • iwrobot schrieb:

    ich habe einfach vor jeden fclose(...) ein fflush(...) gesetzt! Jetzt stürzt das Board nnicht mehr so schnell ab. D.h beim ersten ausprobieren hat es bestimmt 5min gehalten. Dann ist es allerdings wieder abgestürzt.

    Aber das fflush hat mir auf jeden Fall geholfen.

    Diese Ausgaben sollen nicht dafür sorgen, dass dein Prorgamm "stabiler" wird. Sie sollen dir zeigen, an welcher Stelle in deinem Code der Absturz passiert.



  • Hallo MFK,

    das weiß ich. Aber das Programm läuft ja nicht stabiler, seit dem ich die ganzen printf() reingeschrieben habe, sondern seit dem ich das fflush() verwendet habe.

    Und das die printf() mir anzeigen sollen, wo der Fehler ist, bzw. wo das Programm abstürzt ist mir auch klar. Nur leider stürzt das Programm an verschiedenen Stellen ab.



  • iwrobot schrieb:

    ich habe einfach vor jeden fclose(...) ein fflush(...) gesetzt! Jetzt stürzt das Board nnicht mehr so schnell ab. D.h beim ersten ausprobieren hat es bestimmt 5min gehalten. Dann ist es allerdings wieder abgestürzt.

    Hmm, das klingt nach irgendeinem Ausdruck mit undefiniertem Verhalten, der dann schliesslich dazu führt. Ein fflush() vor einem fclose() sollte gar keine Auswirkungen haben, weil fclose() den Puffer sowieso leert, bevor es die Datei zurückgibt.

    iwrobot schrieb:

    Kann mir vielleicht jemand sagen, wie schnell so ein C Programm abgearbeitet wird. Ich meine von Befehl zu Befehl brauch der Rechner ja auch eine Zeit.

    Messen hilft. Eine gewisse Genauigkeit haben die Funktionen aus time.h. Falls die nicht reicht, hat das System wahrscheinlich was besseres auf Lager.
    🙂



  • FILE *fp;
    
      fp = fopen( "/sys/class/gpio/gpio85/direction","w");            
      fprintf(fp,"out");                                                
      fclose(fp); /* <--- */
    
      if(!fp)     /* <--- */
      {                                                                        
        printf("Fehler beim oeffnen der direction Datei (Sensor)\n");                  
      }
    

    Das ist nicht dein Ernst, oder?



  • seldon schrieb:

    Das ist nicht dein Ernst, oder?

    Allein aus logischer Sicht, müsste das ins Auge stechen. Aber es steht dem switch( Wiederholung ) in nichts nach.

    Du solltest den ganzen Code nochmal überdenken.

    int signalverarbeiten()
    {
    	FILE* fp;
    	int erg = 0;
    
    	if( fp = fopen("/sys/class/gpio/gpio85/value","r") )
    	{
    		fscanf(fp, "%d", &erg
    		fclose(fp);
    
    		return 1;
    	}
    	else
    		return 0;
    }
    
    int i = 0;
    while( !signalverarbeiten() && i++ < 5 );
    


  • @seldon:

    Was meinst du damit? Ist die Vorgehensweise falsch?

    @FrEEzE2046:

    Deine Aussage verstehe ich nicht. Was ist mit switch(wiederholung)?
    Und was macht denn die while Schleife in deiner Antwort?



  • Du öffnest die Datei, schreibst hinein, schließt sie wieder und prüfst dann, ob das Öffnen funktioniert hat. Wenn also beim Öffnen tatsächlich etwas schief geht, arbeitest du eine ganze Weile mit einem NULL-Zeiger, und dass er dabei abstürzt, ist wenig verwunderlich.

    Richtig wär's etwa so:

    FILE *fp = fopen(...);
    
    if(fp != NULL) {
      /*  Hier kannst du gefahrlos mit der Datei arbeiten */
      fclose(fp);
    } else {
      /* Fehler beim Öffnen */
    }
    


  • Naja, das stimmt nicht ganz. Ich überprüfe noch vor dem schließen der Datei, ob sie geöffnet werden konnte. Aber deine Lösung ist natürlich elganter und übersichtlicher! Ich werde das bestimmt noch ändern. Danke für den Tipp!



  • Aus deinem Code:

    fclose(fp);
    
      if(!fp)
    

    Was passiert da zuerst?

    Abgesehen davon hilft es dir nichts, wenn du prüfst, ob der Zeiger NULL ist, nachdem du in ihm rumgeschrieben hast. Du musst prüfen, ob fp gültig ist, bevor du damit arbeitest, nicht nur bevor du ihn schließt.



  • Hallo seldon,

    du hast mich überzeugt. Ich werde den Code bearbeiten und erneut ausprobieren. Nur momentan hat das Board irgendwelche Probleme mit den Sensoren. Sobald ich den Code verändert und getestet habe, werde ich berichten.



  • iwrobot schrieb:

    Naja, das stimmt nicht ganz. Ich überprüfe noch vor dem schließen der Datei, ob sie geöffnet werden konnte. Aber deine Lösung ist natürlich elganter und übersichtlicher!

    Bitte? Das hat nichts mit eleganter zu tun. Deine "Lösung" ist inexistent, da der Code so wie er ist einfach keinen Sinn macht.

    Noch mal - du machst folgendes:
    1. Datei öffnen
    2. In Datei schreiben
    3. Datei schließen
    4. Überprüfen ob das Dateihandle korrekt ist

    Was denkst du was passiert, wenn "4." negativ ist und du gerade "2." machst?



  • Ich habs gesehen.

    Ich mache es mal so, mal so. Und Ihr habt vollkommen Recht, an mindestens zwei Stellen überprüfe ich das Öffnen der Datei, obwohl ich sie schon geschlossen habe.

    Sorry, ich habe an genau den falschen Stellen nachgeschaut. Ihr habt natürlich Recht. Danke für die Hinweise!



  • Also das Programm stürzt jetzt auf jeden Fall nicht mehr ab. Das ist ja schonmal ein riesen Fortschritt. Allerdings ist die Funktion immer noch nicht so gegeben, wie ich das möchte. Damit muss ich mich aber wahrscheinlich an ein SRF05 Forum oder so was wenden. Ich danke euch auf jeden Fall für eure Hilfe.

    Pascal



  • Vielen Dank nochmal für eure Hilfe.

    Mittlerweile ist das Projekt schon vorgestellt worden. Wem es interessiert kann sich ja mal auf http://iwrobot.bplaced.net/ informieren.

    MFG

    Pascal



  • mngbd schrieb:

    void log(char *s)
    {
        fputs(s, stderr);
        fflush(stderr);
    }
    

    müsste stderr nicht sowieso ungepuffert sein?


Log in to reply