Verhalten von fcloseall und dessen Einsatzgebiet


  • Gesperrt

    @Swordfish sagte in Umgangston:

    Nein, kann man nicht. Dann schlägt eine Schreiboperation fehl. Das heißt nicht, daß einem der Stream plötzlich unterm Arsch weggezogen wird.

    Das gilt es auszuprobieren. Ich behaupte, dass nach einem fcloseall() ein Schreibzugriff fehlschlägt, nicht aber das Programm abstürzt. Vielleicht hat ja jemand Bock das zu testen. Ich mache das morgen mal.



  • @Wade1234 sagte in Umgangston:

    also ich habs jetzt nicht nachgeguckt, aber ich meine, dass du dann end of file bekommst und nicht invalid handle.

    Invalid handle wäre ja noch toll. _fcloseall macht aber sämtliche FILE* ungültig. Also nicht dass das Objekt dahiner als "ich bin jetzt zu" markiert wird, sondern alle FILE Zeiger sind danach ungültig. Also nix mit "invalid handle" sondern KABOOM!



  • @RBS2 sagte in Umgangston:

    Das gilt es auszuprobieren.

    Da braucht man nichts auszuprobieren. RTFM reicht.

    @RBS2 sagte in Umgangston:

    Dann schlägt eine Schreiboperation fehl.

    bezog sich auf "Was auch passiert, wenn z.B. dein Speicherstick voll wird".



  • @RBS2 sagte in Umgangston:

    Das gilt es auszuprobieren. Ich behaupte, dass nach einem fcloseall() ein Schreibzugriff fehlschlägt, nicht aber das Programm abstürzt. Vielleicht hat ja jemand Bock das zu testen. Ich mache das morgen mal.

    Ich habe es ausprobiert, und zwar bevor ich anfing hier heute eine etwas derbere Ausdrucksweise zu verwenden. Weil ich mir nur 99% sicher war aber nicht 100%. Auf Windows, Visual Studio 2017. ES CRASHT. Access-Violation.

    Alter Schwede 🤦♂



  • @hustbaer sagte in Umgangston:
    etwas derbere Ausdrucksweise zu verwenden.

    witzig, dass wir hier in einem thread, der davon handelt, dass der umgangston schlecht ist, irgendwas ausdiskutieren und der umgangston dabei schlecht ist. 😃



  • @hustbaer sagte in Umgangston:

    Alter Schwede 🤦♂

    Wenn schon mit Style.


  • Gesperrt

    @hustbaer sagte in Umgangston:

    Ich habe es ausprobiert, und zwar bevor ich anfing hier heute eine etwas derbere Ausdrucksweise zu verwenden. Weil ich mir nur 99% sicher war aber nicht 100%. Auf Windows, Visual Studio 2017. ES CRASHT. Access-Violation.

    Danke für die Info. Ich werde versuchen, mit etwa den gleichen Voraussetzungen den Crash zu reproduzieren. 🐱


  • Gesperrt

    @Wade1234 sagte in Umgangston:

    witzig, dass wir hier in einem thread, der davon handelt, dass der umgangston schlecht ist, irgendwas ausdiskutieren und der umgangston dabei schlecht ist.

    Was lernen wir daraus? Also trotz allen Gepöbels immer cool bleiben. Guter Thread! 🔝


  • Gesperrt

    @Wade1234 sagte in Umgangston:

    also ich habs jetzt nicht nachgeguckt, aber ich meine, dass du dann end of file bekommst und nicht invalid handle.

    Was letztlich egal ist. Die Frage ist "Fehlercode oder Absturz". Husti sagt, das Programm nippelt ab.



  • The fread function reads, into the array pointed to by ptr, up to nmemb elements whose size is specified by size, from the stream pointed to by stream.

    Das selbe in grün für fwrite(), fclose() und andere. Die Funktionen (oder irgendwelche von ihnen aufgerufene) müssen den Pointer dereferenzieren ~> kabumm.



  • @RBS2 sagte in Umgangston:

    Was letztlich egal ist. Die Frage ist "Fehlercode oder Absturz". Husti sagt, das Programm nippelt ab.

    "debug assertion failed" unter visual studio bzw. mit debug informationen, "project1.exe funktioniert nicht mehr" wenn als "release" compiliert nach _fcloseall. gleiches verhalten, wenn die datei schreibgeschützt ist (logisch, NULL). stimmt also!

    wie das jetzt mit dem vollen laufwerk ist, weiß ich nicht, aber wahrscheinlich schlägt fwrite dann fehl und du kannst ferror auswerten.



  • @Wade1234 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:

    @RBS2 sagte in Umgangston:

    Was letztlich egal ist. Die Frage ist "Fehlercode oder Absturz". Husti sagt, das Programm nippelt ab.

    "debug assertion failed" unter visual studio bzw. mit debug informationen, "project1.exe funktioniert nicht mehr" wenn als "release" compiliert nach _fcloseall. gleiches verhalten, wenn die datei schreibgeschützt ist (logisch, NULL). stimmt also!

    wie das jetzt mit dem vollen laufwerk ist, weiß ich nicht, aber wahrscheinlich schlägt fwrite dann fehl und du kannst ferror auswerten.

    Nein, nicht gleiches Verhalten.

    Im "schreibgeschützt" Fall bekommt man einfach einen NULL Zeiger zurück. Das kann man prüfen. Wenn man es nicht prüft ist das ein Fehler den man selbst gemacht hat, im eigenen Code, der eigenen Komponente.

    Im "no space left on device" Fall bekommt man einen gültigen, funktionierenden, non-NULL FILE*. Wenn man dann versucht etwas damit zu schreiben bekommt man einfach einen Fehlercode von der Schreibfunktion zurück. Kann man ebenso behandeln, wenn man es nicht macht ist man ebenso selbst schuld, eigener Code, eigene Komponente.

    Im _fcloseall Fall dagegen bekommt man auch erstmal einen gültigen, funktionierenden, non-NULL FILE*. Und alles funktioniert erstmal wunderbar. Bis zu dem Zeitpunkt wo z.B. eine andere Komponente, evtl. sogar in einem anderen Thread, _fcloseall aufruft. Und ab dem Moment kracht es dann* wenn man versucht den FILE* nochmal zu verwenden. Der FILE* den man irgendwo in einer Variable gespeichert hat wird dadurch aber nicht NULL, er wird bloss ungültig, "dangling" halt. Grosses Problem, und nicht selbst verursacht. Nicht im eigenen Code, nicht in der eigenen Komponente.

    Also ganz ganz grosser Unterschied. Fall 1 und 2 kann man problemlos behandeln und sollte IMO auch jedes brauchbare Programm behandeln. Fall 3 kann man theoretisch in kleinen, 100% selbstgeschriebenen Programmen (=keine thirdparty Libraries etc.) kontrolliert behandeln, aber mMn. nur wenn man total bekloppte Einschränkungen akzeptiert. Praktisch, in realen, grösser als winzigen Projekten ist Fall 3 aber ein verdammtes riesen Problem. Ca. so gross wie andere fremden Speicher zu überschreiben oder alles grundsätzlich und überall über globale Variablen zu machen ("wer braucht schon Parameter?").


    *: Oft, aber natürlich nicht garantiert. Es kann quasi fast alles passieren, z.B. dass man ins falsche File schreibt und es nicht mal merkt. Oder State einer dritten Komponente zerschiesst ohne dass gleich etwas abstürzt. Undefiniert halt. Schlecht.


    ps: Mir fällt gerade auf, du könntest "gleiches Verhalten" auch auf dein Testprogramm bezogen haben, wo du der Einfachkeit halber den NULL Check weggelassen hast. In dem Fall ja, klar, vermutlich gleiches Verhalten. Nur halt nicht gleiches Problem in realer Software, da 1x problemlos behandelbar und 1x totale Katastrophe.



  • @RBS2 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:

    @Wade1234 sagte in Umgangston:

    witzig, dass wir hier in einem thread, der davon handelt, dass der umgangston schlecht ist, irgendwas ausdiskutieren und der umgangston dabei schlecht ist.

    Was lernen wir daraus? Also trotz allen Gepöbels immer cool bleiben. Guter Thread! 🔝

    Oder auch dass man ruhig erstmal nachfragen kann, wenn...

    • jemand irgendwo sagt "X hat in sauberer Software nix verloren" und
    • man irgendwie nicht so ganz versteht warum/das nicht so sieht und
    • man nicht so genau weiss was X eigentlich ist/tut

    ...bevor man anfängt ihn darüber zu belehren dass man das auch anders sehen kann.



  • @hustbaer sagte in Verhalten von fcloseall und dessen Einsatzgebiet:

    ps: Mir fällt gerade auf, du könntest "gleiches Verhalten" auch auf dein Testprogramm bezogen haben, wo du der Einfachkeit halber den NULL Check weggelassen hast. In dem Fall ja, klar, vermutlich gleiches Verhalten. Nur halt nicht gleiches Problem in realer Software, da 1x problemlos behandelbar und 1x totale Katastrophe.

    ja das war auch auf mein (windows-) testprogramm bezogen.

    unter freebsd stürzt da übrigens nichtmal was ab, das programm läuft ganz normal. die schreiboperation nach log.txt erfolgt, weil der stdout ja geschlossen ist. edit: moment, da stimmt irgendwas mit der ausgabe nicht. ich erhalte n == 5 und errno 9 (ungültige datei). bug im compiler?

    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
            int file;
            int n;
            char str[100];
            char str1[100];
            char str2[100];
    
            file = open("test.txt", O_RDWR | O_CREAT);
            if(file == -1)
            {
                    printf("open failed\n");
                    return 1;
            }
    
            fcloseall();
            //close(file);
    
            n = write(file, "test", 5);
            close(file);
    
            file = open("log.txt", O_WRONLY);
    
            sprintf(str1, "%d bytes written.\n", n);
            write(file, str1, strlen(str1) + 1);
    
            if(n <= 0)
            {
                    sprintf(str2, "errno: %d\n", errno);
                    write(file, str2, strlen(str2) + 1);
            }
    
            close(file);
    
    
            return 0;
    }
    
    


  • @Wade1234 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:

    unter freebsd stürzt da übrigens nichtmal was ab, das programm läuft ganz normal. die schreiboperation nach log.txt erfolgt, weil der stdout ja geschlossen ist. edit: moment, da stimmt irgendwas mit der ausgabe nicht. ich erhalte n == 5 und errno 9 (ungültige datei). bug im compiler?

    Das könnte damit zu tun haben dass undefiniertes Verhalten undefiniertes Verhalten ist.



  • undefiniertes verhalten bedeutet doch, dass man die bedienungsanleitung des compilers lesen soll, oder nicht?



  • @Wade1234
    Nö, undefiniertes Verhalten bedeutet, dass das Programm machen darf, was es will, und der Compiler trotzdem alles richtig gemacht hat. Nur halt der Programmierer nicht.


  • Administrator

    @Wade1234 sagte in Verhalten von fcloseall und dessen Einsatzgebiet:

    undefiniertes verhalten bedeutet doch, dass man die bedienungsanleitung des compilers lesen soll, oder nicht?

    Ist das als Witz gemeint? Falls nicht: Geh bei undefiniertem Verhalten davon aus, dass theoretisch dein Programm die Welt explodieren lässt. Es ist undefiniert, es kann alles passieren. Der Compiler definiert da nichts, er nimmt schlicht keine Rücksicht. Sonst wäre es Implementations spezifisches Verhalten.



  • und ihr könnt da keinen "designfehler" oder so entdecken?




Anmelden zum Antworten