Login
Newsletter
Werbung

Thema: Änderung in glibc deckt Fehler in Anwendungen auf

63 Kommentar(e) || Alle anzeigen ||  RSS
Kommentare von Lesern spiegeln nicht unbedingt die Meinung der Redaktion wider.
2
Von pvb123 am Fr, 12. November 2010 um 11:36 #

Ich schließe mich der Auffassung von Linus Torvalds an.

[
| Versenden | Drucken ]
  • 1
    Von CRB am Fr, 12. November 2010 um 11:39 #

    Auf eine gewisse Kompatibilität innerhalb einer Serie sollte man schon achten. Oder gleich sauber programmieren.

    [
    | Versenden | Drucken ]
    • 1
      Von Hans am Fr, 12. November 2010 um 11:41 #

      Die Kompatibilität ist gegeben. Denn memcpy auf überlappende speicherbereiche aufzurufen ist 'undefined behaviour'. Und sich als programmierer auf sowas zu verlassen ist halt falsch. Denn undefined behaviour ist und bleibt undefined. Mal kanns funktionieren, mal kann es fehlschlagen. Ich kann eigentlich den glibc programmieren voll und ganz zustimmen...

      [
      | Versenden | Drucken ]
      • 1
        Von CRB am Fr, 12. November 2010 um 11:47 #

        ... Wenn man es viele Jahre lang zulässt und dann urplötzlich ändert, dann ist es eine Inkompatibilität.

        Zudem kann man sich auch als GLibC-Entwickler nicht darauf verlassen, dass die anderen keine undefinierten Möglichkeiten verwenden, denn:

        undefiniert != nicht erlaubt

        Die Lösung wäre es also gewesen zu sagen: in GLibC 2.11x ist es noch möglich, mit der 2.12x wird es nicht mehr erlaubt sein.

        Ist ja schön, dass die GLibC-Entwickler das jetzt bereinigen, vorher sollten sie sich jedoch Gedanken um die Auswirkungen machen.

        [
        | Versenden | Drucken ]
        • 1
          Von phreck am Fr, 12. November 2010 um 12:13 #

          Ich bin mit den glibc-Programmierern.

          C ist keine Programmiersprache für Anfänger, und jeder sollte wissen, was undefined behaviour bedeutet und wie es sich auswirken kann. Es gefährdet die Kompatibilität des eigenen Programms in all Richtungen: Aufwärts, Abwärts, läuft auf System X aber nicht auf Y (bspw. amd64 vs. sparc), et cetera.

          "Works for me"-Programmierer sind selbst Schuld, wenn sie sich auf undokumentierte Erweiterungen verlassen.


          > ... Wenn man es viele Jahre lang
          > zulässt und dann urplötzlich ändert,
          > dann ist es eine Inkompatibilität.

          Die Programme, die sich auf undefiniertes Verhalten verlassen, sind an sich schon per definitionem inkompatibel.

          Der C-Compiler kann nicht inkompatibel werden, wenn er das Verhalten von etwas ändert, das nicht vom Standard sanktioniert ist.

          Ergo, der gemeinsame Nenner von glibc und den Clients von glibc ist der C-Standard (und POSIX), und wer hier nicht nach den Regeln spielt und demnach nicht kompatibel ist sind die Clients.

          [
          | Versenden | Drucken ]
          • 1
            Von pvb123 am Fr, 12. November 2010 um 12:44 #

            Deshalb schafft es Linux auch nicht auf den Desktop.
            Es gibt nun mal Anwender, die mit sehr alten kommerziellen Programmen arbeiten, weil Sie Lizenzkosten sparen wollen und die neuen Features nicht vermissen. Das funktioniert nur dann, wenn sich das Fundament nicht ändert.

            In der Konsequenz müssten alle Programme vollständig statisch gelinkt sein.

            Es geht auch nicht darum, ob C/C++ nun nichts für Anfänger ist oder nicht.
            Tatsache ist nun mal, dass diese Probleme in der Praxis auftauchen (z.B. Flash).

            Es geht darum, dass der Anwender es nicht toleriert, wenn eine Anwendung, die immer zur vollsten Zufriedenheit arbeitete nach einem Betriebssystem Update auf einmal nicht mehr läuft.

            Es sollte da ein gesunder Zwischenweg zwischen dem Windows Ansatz und der bei Linux vertretenen reinen Lehre sein.

            [
            | Versenden | Drucken ]
            • 1
              Von unknown am Fr, 12. November 2010 um 13:09 #

              Das hast du auch bei Windows.

              Hast wahrscheinlich noch nie ein Wechsel von WinXP -> Vista oder Win7 gemacht.

              Ausserdem ist man bei Linux bezüglich Lizenkosten günstiger dran. Bei Windows kostet allein schon ein Upgrade zusätzliche Lizenzkosten.

              Wenn allte Programme nicht getauscht werden sollen, wieso sollte man auch das Betriebssystem tauschen?

              [
              | Versenden | Drucken ]
              • 1
                Von pvb123 am Fr, 12. November 2010 um 13:25 #

                > Hast wahrscheinlich noch nie ein
                > Wechsel von WinXP -> Vista oder Win7
                > gemacht.
                Nein, aber DOS->alle Windows bis XP außer ME

                > Ausserdem ist man bei Linux
                > bezüglich Lizenkosten günstiger
                > dran.
                Ich habe von kommerziellen Programmen gesprochen.

                > Wenn allte Programme nicht getauscht
                > werden sollen, wieso sollte man auch
                > das Betriebssystem tauschen?
                Z.B. weil der alte Computer kaputt ist und ersetzt werden musste.
                VMware ist da nur die 2 beste Lösung.

                PS:
                Einen Vorteil haben Open Source Programme, die auf vielen Plattformen laufen und die schon viele verschiedene Compiler gesehen haben.
                Sie sind sauberer und besser debuged.

                [
                | Versenden | Drucken ]
                • 1
                  Von unknown am Fr, 12. November 2010 um 13:55 #

                  >Nein, aber DOS->alle Windows bis XP außer ME
                  Nicht umsonst gibt es dosbox. ;-)

                  >Ich habe von kommerziellen Programmen gesprochen.
                  Ich auch, ausserdem .. Kosten bleiben Kosten.
                  Wenn ein Hersteller sagt, dass seine Software nur auf Windows NT oder 2000 lauffähig ist, dann ist es ebon so. Da kann man auch nicht einfach das System ändern.

                  >Z.B. weil der alte Computer kaputt ist und ersetzt werden musste.
                  >VMware ist da nur die 2 beste Lösung.
                  Wenn eine Workstation kaput geht, kann man ja das selbe OS nochmal installieren. Ausserdem wird Produktivumgebungen nicht mal ebenso etwas verändert.

                  [
                  | Versenden | Drucken ]
              1
              Von phreck am Fr, 12. November 2010 um 13:14 #

              Ich muss Linux auch nicht unbedingt auf dem Desktop haben. Ich meine, ich habe es schon, aber mir geht es weniger um die Massenverbreitung als um das System selbst.

              Imho ist das auch nicht der Grund für die Nichtverbreitung, sondern eher fehlendes Marketing und die Legacy von Windows unter zivilen Usern.

              [
              | Versenden | Drucken ]
              1
              Von phreck am Fr, 12. November 2010 um 13:20 #

              Ich muss Linux auch nicht unbedingt auf dem Desktop haben. Ich meine, ich habe es schon, aber mir geht es weniger um die Massenverbreitung als um das System selbst.

              Imho ist das auch nicht der Grund für die Nichtverbreitung, sondern eher fehlendes Marketing und die Legacy von Windows unter zivilen Usern.

              [
              | Versenden | Drucken ]
              1
              Von Sid Burn am Fr, 12. November 2010 um 14:24 #

              Deshalb schafft es Linux auch nicht auf den Desktop.
              Hat mit dem Thema gar nichts zu tun. Die meisten nutzen Distributionen mit Release zyklen. Ein bereits vorhandene Distribution wird daran absolut gar nichts ändern. Da sie die neuste glibc version gar nicht erst einspielen. Das die Software Funktioniert ist dann die Sache der Distribution.

              Es gibt nun mal Anwender, die mit sehr alten kommerziellen Programmen arbeiten, weil Sie Lizenzkosten sparen wollen und die neuen Features nicht vermissen. Das funktioniert nur dann, wenn sich das Fundament nicht ändert.
              Und wo soll jetzt der unterschied zu irgendeinem anderen System sein? Wenn ich irgendeine kommerzielle Software habe und das Fundament sich nicht ändern darf dann nutzt du für immer Windows 2000, Mac OS X 10.4, Debian Lenny etc. pp.

              Daher das Fundament bleibt gleich und das war es. Ob die kommerzielle Software dann noch unter einem Windows 7 oder Debian Squeeze etc. läuft muss man entsprechend Testen.

              Ich sehe jetzt nicht was hier bei GNU/Linux generell anders sein sollte als bei irgendeinem anderem System.

              Tatsache ist nun mal, dass diese Probleme in der Praxis auftauchen (z.B. Flash).
              Natürlich ist das Tatsache. Es tauchen auch immer wiedr Sicherheitslücken, Bugs etc. auf. Softwrae wird von menschen gemacht und die sind nunmal nicht Fehlerfrei. Und wenn solche Sachen auftreten muss man sie eben beiseitigen. Das ist aber eine Tatsache die auch wieder für jedes System und jede Software gilt. Mit Linux auf dem Desktop etc. hat das absolut 0 zu tun.

              s geht darum, dass der Anwender es nicht toleriert, wenn eine Anwendung, die immer zur vollsten Zufriedenheit arbeitete nach einem Betriebssystem Update auf einmal nicht mehr läuft.
              Dann muss er sich an den Hersteller wenden und schauen das diese die Software Updaten. Das ist nunmal leider so und findest du auch wieder bei jedem OS. Nicht alles was auf Windows 2000 lief, lief auf XP, mit Vista und 7 hast du wieder das gleiche Problem. Das passiert bei Windows sogar zwischen den SPs.

              Wenn du aber übrigens ein GNU/Linux System nutzt dann hast du in der Regel ja alle Applikationen dabei und die Distribution kümmert sich darum das alles läuft. Das gilt natürlich nur ausschließlich für Open Source. Closed Source Software kann ja nicht von anderen verbessert werden.

              Es sollte da ein gesunder Zwischenweg zwischen dem Windows Ansatz und der bei Linux vertretenen reinen Lehre sein.
              Welcher gesunder Zwischenweg zwischen Windows und Linux? Alle Punkte die du genannt hast sind generelle Probleme die vorallem auf Windows zutreffen.

              Deine genannten Punkte treffen sogar am seltesten auf wenn du eine GNU/Linux Distribution und Open Source Software nutzt. Da die Distribution alle Punkte übernimmt und sich um wartung Bugfixen kümmert. Jede Software in den versionen bereit stellt wie das System zusammen passt etc.

              Von daher hast du entweder keien Ahnung worüber du redest, oder dir ist gar nicht bewusst was du da überhaupt redest.

              [
              | Versenden | Drucken ]
          0
          Von hhb am Fr, 12. November 2010 um 13:30 #

          undefiniert != nicht erlaubt
          Oh weia. Wenn du als Entwickler wissentlich Code mit undefiniertem Verhalten erlaubst, möchte ich dein Projekt nicht benutzen.

          [
          | Versenden | Drucken ]
          • 1
            Von krake am Fr, 12. November 2010 um 14:17 #

            Es muss ja nicht wissentlich sein, ist mir selber schon mal passiert.

            Bei mir war es ein Debugoutput in der Form von
            printf( "...%s....", variable);

            Wenn "variable" null ist, ist das üblicherweise kein Problem, die Ausgabe ist dann "(null)" oder ähnliches.
            Offiziell ist das Verhalten in diesem Fall aber nicht definiert, die libc unter Solaris macht dort explizit keine Prüfung auf null und resultiert damit in einer Nullpointerdereferenzierung und in Folge in einem Crash.

            [
            | Versenden | Drucken ]
            • 1
              Von Trolly am Fr, 12. November 2010 um 15:24 #

              Bei mir war es ein Debugoutput in der Form von printf( "...%s....", variable);

              Nunja, wenn das Verhalten dann undefiniert ist, dass wird printf schlimmstenfalls irgendwas ausgeben. Das ärgert dann nur dich als Entwickler, weil da nichts Sinnvolles bei rauskommt.

              Aber sich bei grundlegender Funktionalität darauf zu verlassen ist grob fahrlässig.

              [
              | Versenden | Drucken ]
              • 1
                Von phreck am Fr, 12. November 2010 um 16:14 #

                Genie. Selbst bei reinem Lesezugriff kann alles möglich passieren. Ein un-alligned read kann bspw. katastrophal im Tod deines Prozesses münden.

                Ich glaube, nach diesem Post höre ich auf mit dir zu diskutieren. Gibst dich als Top-Coder aus, zeigst aber Mangelwissen bei Grundlagen der Sicherheit.

                [
                | Versenden | Drucken ]
                1
                Von krake am Fr, 12. November 2010 um 16:39 #

                ...dass wird printf schlimmstenfalls irgendwas ausgeben

                Das printf nicht mehr, die Shell gibt dann segmentation fault aus.

                Das ärgert dann nur dich als Entwickler, weil da nichts Sinnvolles bei rauskommt.

                Oder den Benutzer, außer er hat das Programm ohnehin nur irrtümlich gestartet und bisher keinen Weg gefunden, es zu beenden.

                [
                | Versenden | Drucken ]
        1
        Von pvb123 am Fr, 12. November 2010 um 12:05 #

        Was ist hier 'undefined behaviour' ?

        SYNOPSIS
        #include
        void *memcpy(void *dest, const void *src, size_t n);

        DESCRIPTION
        The memcpy() function copies n bytes from memory area
        src to memory area dest. The memory areas should not overlap.
        Use memmove(3) if the memory areas do overlap.

        Mal abgesehen von dem Kommentar in DESCRIPTION (evtl. kürzlich ergänzt). Würde ich annehmen, dass das in etwa so gelöst ist und keine Probleme macht.

        for(int i=0; i< n; i++)*dest++ = *src++;

        Es kann nicht angehen, dass man das Fundament ändert und dann 1000 Häuser zusammenfallen. Wie z.B. auch Fash :-)

        [
        | Versenden | Drucken ]
        • 1
          Von mrpi am Fr, 12. November 2010 um 12:13 #

          "evtl. kürzlich ergänzt": Ja, im Jahre 1989

          http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.14.html#memcpy

          2.14.4 memcpy

          Declaration:

          void *memcpy(void *str1, const void *str2, size_t n);

          Copies n characters from str2 to str1. If str1 and str2 overlap the behavior is undefined.

          Returns the argument str1.

          [
          | Versenden | Drucken ]
          1
          Von phreck am Fr, 12. November 2010 um 12:18 #

          Die Synposis ist aber nicht die volle Definition. Die Description gehört vollkommen dazu. Deine Implementierung ist irrelevant.

          Und im Zweifel einfach in den Standard schauen, ich habe auf allen meinen Entwicklungsrechnern (Beruf und Hobby) alle relevanten Standards bzw. Drafts (so wie man immer die Anleitung des Autos dabei haben sollte):

          7.21.2.1 The memcpy function:
          "The memcpy function copies n characters from the object pointed to by s2 into the
          object pointed to by s1.Ifcopying takes place between objects that overlap, the behavior is undefined"

          [
          | Versenden | Drucken ]
          • 1
            Von pvb123 am Fr, 12. November 2010 um 12:26 #

            > Und im Zweifel einfach in den Standard schauen, ich habe auf allen meinen > Entwicklungsrechnern (Beruf und Hobby) alle relevanten Standards bzw.
            > Drafts (so wie man immer die Anleitung des Autos dabei haben sollte):

            Das habe ich auch:
            man memcpy

            Es sollte hier aber nicht um Prinzipienreiterei gehen, sondern um die Praxis.
            Es scheint nun mal so zu sein, dass es Anwendungen gibt, die dann nicht mehr laufen (z.B. Flash). Eventuell betrifft das sogar viele Anwendungen. Und es betrifft natürlich noch mehr Anwender.

            Deshalb gebe ich Linus recht.

            PS:
            Jetzt könnten wir einen sehr langen thread über den Begriff "frickeln" starten.

            [
            | Versenden | Drucken ]
            • 1
              Von phreck am Fr, 12. November 2010 um 13:06 #

              Die manpages sind nicht der Standard. Die Formulierung ist aber ähnlich, und beide sagen eindeutig aus, dass überlappende Arrays als Parameter zu memcpy zu undefiniertem Verhalten führen.

              Und wer undefiniertes Verhalten ausnutzt ist imho in der Tat ein Frickler.

              Und so sehr ich Linus schätze, wie Raymond sagt, maybe he's "the second coming of Ken" [0], ich denke es ist durchaus nicht unüberheblich auf nicht festegelegtes Verhalten zu pochen und memcpys Evolution dadurch zu verkrüppeln.

              Vertrauen auf gcc-Extensions ist ein Ding, aber auf ein bestimmtes unbestimmtes Verhalten einer 3rd-Party-Library, welche den C-Standard implementiert, zu vertrauen, ist eine andere, unsaubere.

              [0]: http://www.vanadac.com/~dajhorn/novelties/ESR%20-%20Curse%20Of%20The%20Gifted.html

              [
              | Versenden | Drucken ]
              1
              Von phreck am Fr, 12. November 2010 um 13:08 #

              Und als Nachtrag zu mir selbst (ich sollte mir einen Account hier anlegen):

              > und memcpys Evolution dadurch zu verkrüppeln.

              ... und dadurch all jene zu bestrafen, welche sich an den Standard halten. Und ich behaupte, dass ist die absolute Mehrheit.

              [
              | Versenden | Drucken ]
              • 1
                Von DriverDevel am Fr, 12. November 2010 um 20:21 #

                Das Problem an dieser Einstellung ist, dass Du in einem (sau-)mäßig großen Programm (>= 1MLOC) dann evt. _irgendwo_ doch eine nicht konforme Stelle hast (und wenn es in einer blöden nicht modifizierbaren 3rd-Party-Lib ist!) Und dann knallt's eben.

                Daher bin ich zwar ebenfalls für Deprecation, allerdings per Kompatibilitäts-Check und Warning (und das dann zu einem sauberen glibc-Versionswechsel entfernen).

                BTW: ja, dieses Valgrind-Warning kenne ich sehr gut...

                [
                | Versenden | Drucken ]
            1
            Von hjb am Fr, 12. November 2010 um 12:50 #

            If copying takes place between objects that overlap, the behavior is undefined
            Die Formulierung ist zwar kreuzdämlich, aber es ist eindeutig, dass damit gemeint ist, dass solche Aufrufe verboten sind. Ich bin ziemlich sicher, dass POSIX und alle relevanten Bücher dies auch irgendwo sagen.

            [
            | Versenden | Drucken ]
            • 0
              Von hhb am Fr, 12. November 2010 um 13:43 #

              Die Formulierung ist zwar kreuzdämlich, aber es ist eindeutig, dass damit gemeint ist,
              Was ist denn daran "kreuzdämlich"? Und darüber, was damit gemeint ist, muss man nicht spekulieren. "Undefined behavior" ist ein Konzept, dass sich durch die gesamte C-Standardisierung zieht, und bei dem jedem C Programmier klar sein sollte, was damit gemeint ist - sonst ist er eine tickende Zeitbombe. Denn ziemlich viel in C ist "undefined behavior" oder "implementation-defined behavior". Das macht die Sprache ja so gefährlich.

              Kurz gesagt bedeutet "undefined bahavior", dass alles passieren kann. Es kann so funktionieren, wie der Programmierer es sich vorstellt. Es kann einen Crash geben. Es kann dein .ssh und .gnupg Verzeichnis als zip gepackt an ronald@mcdonald.com verschickt werden. Es können die Lottozahlen von nächster Woche vorausgesagt werden. Es kann eine Atomrakete in Richtung Andorra gestartet werden (entsprechende Hardware vorausgesetzt). Es kann passieren, dass einem Drachen aus der Nase fliegen (Standard-Erklärung frei nach comp.lang.c). Aber nur bei jedem zweiten Vollmond im Jahr, nachts um 12:00.

              All dies kann übrigens schon zur Compile-Zeit passieren. Dazu braucht man das entsprechende Programm nicht mal zu starten.

              Der gcc hatte früher mal ein Easter-Egg, dass bei einem Konstrukt mit "implementation defined behavior" Emacs mit Towers of Hanoi gestartet wurde.

              [
              | Versenden | Drucken ]
              • 1
                Von Trolly am Fr, 12. November 2010 um 15:29 #

                Denn ziemlich viel in C ist "undefined behavior" oder "implementation-defined behavior".

                Ach ja? Na, dann fang mal an mit dem Auflisten.
                Sämtliches undefiniertes Verhalten, das ich aus C kenne sind Dinge, die ein Programmierer nur aus reiner Dummheit verwenden würden (Division durch 0, etc.).

                [
                | Versenden | Drucken ]
                • 0
                  Von hhb am Fr, 12. November 2010 um 15:46 #

                  Na, dann fang mal an mit dem Auflisten.
                  Nein, ich werde jetzt sicher nicht den C-Standard vorlesen und Dinge auflisten. Lesen sollte ein Programmierer schon können.

                  Aber ich kann aus den >100 Einträgen aus dem C-Standard mal zwei, drei häufige Fälle nennen, die mir zuerst in den Sinn kommen.

                  Undefined behavior:
                  - Integer overflow
                  - fflush() auf Eingabeströme (dieser Fall wird sogar oft genug falsch gelehrt)
                  - lesen von nicht-initialisierten Variablen mit "automatic storage". (z.B. int i; i++;)

                  Implementation-defined behavior:
                  - bitweise Operationen auf vorzeichenbehafteten Ganzzahltypen
                  - Casting von Pointer in Integer und zurück
                  - alles, was mit #pragma zu tun hat

                  [
                  | Versenden | Drucken ]
                  • 1
                    Von Trolly am Fr, 12. November 2010 um 16:04 #

                    Toll. Die Verwendung aller undefinierten Verhalten, die du aufgelistet hast, sind reine Dummheit.

                    Integer overflow? Tja, da hat wohl jemand keine Ahnung, wie groß die Zahlen in seinem Programm werden können. Wenn es dazu kommt, dann ist schon im Design der Software was grob falsch gelaufen.

                    fflush() auf Eingabströme? Ernsthaft? Wo wird sowas denn gelehrt?

                    Lesen von nicht-initialisierten Variablen? Es wird sogar schon kompletten Anfängern beigebracht dies nicht zu tun, selbst bei Programmiersprachen bei denen eine automatische Initialisierung vorgesehen ist.

                    [
                    | Versenden | Drucken ]
                    • 0
                      Von hhb am Fr, 12. November 2010 um 16:08 #

                      Es wird sogar schon kompletten Anfängern beigebracht
                      Sag das mal dem OpenSSL Team.

                      Ehrlich, mich interessiert nicht die Bohne, ob du dich für den C-Halbgott hälst oder nicht. Fakt bleibt, dass in C "sehr viele" Konstrukte undefiniertes Verhalten haben.

                      [
                      | Versenden | Drucken ]
                      1
                      Von phreck am Fr, 12. November 2010 um 16:10 #

                      Es ist dumm, sich nicht für dumm oder für unfehlbar zu halten.

                      Fehler passieren jedem, und es ist unmöglich, Bugs in einem nicht trivialem Programm auszuschließen.

                      [
                      | Versenden | Drucken ]
                  1
                  Von phreck am Fr, 12. November 2010 um 16:03 #

                  Und ich finde es dumm, so einen Satz zu posten, ohne auch nur einmal in den Standard geguckt zu haben.

                  5.1.1.2, Translation Phases, 4: "If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), [b]the behavior is undefined[/b]."

                  5.2.1, Character Sets, 4: "If any other characters are encountered [...] the [b]behavior is undefined[/b]"

                  6.2.2, Linkage of Identifiers, 7: "If, within a translation unit, the same identifier appears with both internal and external
                  linkage, [b]the behavior is undefined[/b]."

                  6.2.4, Storage durations of objects, 2: "If an object is referred to outside of its
                  lifetime, [b]the behavior is undefined[/b]."

                  6.2.6.1, General, 5: "If the stored
                  value of an object has such a representation and is read by an lvalue expression that does not have character type, [b]the behavior is undefined[/b]. If such a representation is produced
                  by a side effect that modifies all or anypart of the object by an lvalue expression that
                  does not have character type, the [b]behavior is undefined[/b]."

                  6.2.6.2, Integer Types, 4: "If the implementation does not support negative zeros, [b]the behavior[/b] of the &, |, ^, ~, operators with arguments that would produce such a value [b]is undefined[/b]."

                  6.2.7, Compatible type and composite type, 2: "All declarations that refer to the same object or function shall have compatible type;
                  otherwise, [b]the behavior is undefined[/b]."

                  6.3.1.4, Real floating and integer, 1: "If the value of
                  the integral part cannot be represented by the integer type, [b]the behavior is undefined[/b]"

                  6.3.1.4, Real floating and integer, 2: "If the value being converted is outside the range of
                  values that can be represented, [b]the behavior is undefined[/b]."

                  6.3.1.5, Real floating types, 2: "If the value being converted is outside the range of
                  values that can be represented, [b]the behavior is undefined[/b]."

                  6.3.2.1, Lvalues, arrays, and function designators, 1: "An lvalue is an expression with an object type or an incomplete type other than void;
                  53)
                  if an lvalue does not designate an object when it is evaluated, [b]the behavior is undefined[/b]."

                  6.3.2.1, Lvalues, arrays, and function designators, 2: "If the lvalue has an incomplete type and does not have array type, [b]the behavior is
                  undefined[/b]."

                  6.3.2.1, Lvalues, arrays, and function designators, 2: "If the array object has register storage class, the
                  [b]behavior is undefined[/b]."

                  6.3.2.3, Pointers, 6: "If the result cannot be represented in the integer type,
                  [b]the behavior is undefined[/b]"


                  Und alleine bis 7.2 Diagnostics gibt es noch ca. [b]60 weitere undefined behaviors[/b]. Danach wurde mir das Zählen zu mühsam.

                  [
                  | Versenden | Drucken ]
                  • 1
                    Von Trolly am Fr, 12. November 2010 um 16:11 #

                    Jo, und all das sind Dinge, die eine Sprache nicht definieren kann, weil es dafür keine allgemeingültige Lösung gibt.

                    Um mal ein Beispiel rauszusuchen:

                    6.3.1.4, Real floating and integer, 1: "If the value of
                    the integral part cannot be represented by the integer type, the behavior is undefined"

                    Klar könnte die Sprache definieren, dass der Integer dann 0 ist. oder INT_MAX, oder wasauchimmer. In jedem Fall ist das Ergebnis aber nicht das, was ein Entwickler haben möchte. Ganz abgesehen davon, dass er dann sein Programm nicht vernünftig designt hat.

                    [
                    | Versenden | Drucken ]
                    • 1
                      Von phreck am Fr, 12. November 2010 um 16:23 #

                      Das grenzt langsam an Idiotie, wenn man in Betracht zieht, für wie gut du dich hälst.


                      > Jo, und all das sind Dinge, die eine Sprache nicht definieren kann,

                      Doch, kann sie. Es kann z.B. definiert sein, dass eine Division durch 0 eine divison_by_zero exception schmeißt. Oder sie könnte errno setzen und das Ergebnis bei 0 belassen.


                      > In jedem Fall ist das Ergebnis aber nicht das, was ein Entwickler haben möchte.

                      Das spielt auch keine Rolle. Definiertes Verhalten ist definiertes Verhalten, und ich könnte mich bspw. darauf verlassen, dass im Falle eines Overflows das Ergebnis INT_MAX ist. Bei undefiniertem Verhalten kann ich das nicht und ich muss Vorkehrungen treffen, damit dieser Fall nie eintritt.

                      Dura Lex sed Lex.

                      [
                      | Versenden | Drucken ]
                      • 1
                        Von Trolly am Fr, 12. November 2010 um 16:28 #

                        Doch, kann sie. Es kann z.B. definiert sein, dass eine Division durch 0 eine divison_by_zero exception schmeißt. Oder sie könnte errno setzen und das Ergebnis bei 0 belassen.
                        C hat weder Exceptions noch ist es eine funktionale Sprache in dem Sinne, als dass eine Division etwas anderes als eine Zahl zurückliefern könnte.

                        und ich könnte mich bspw. darauf verlassen, dass im Falle eines Overflows das Ergebnis INT_MAX ist
                        Und woher willst du wissen, dass das Ergebnis nicht genau INT_MAX ist und gar kein Überlauf aufgetreten ist? Erkennst du das dann als Fehler?

                        [
                        | Versenden | Drucken ]
                        • 1
                          Von phreck am Fr, 12. November 2010 um 16:33 #

                          > C hat weder Exceptions
                          Das war ein C++-Beispiel. Exception Handling gibt es aber sehr wohl auch in C: http://www.on-time.com/ddj0011.htm .

                          > noch ist es eine funktionale Sprache in dem Sinne

                          Es ist in keinem Sinne eine funktionale Programmiersprache.

                          > als dass eine Division etwas anderes als eine Zahl zurückliefern könnte.

                          Was? Undefined behaviour kann heißen, dass das Resultat 0 ist bei Compiler X auf Linux um 12:33 Uhr. Es kann aber auch heißen dass nichts zurückgegeben wird sondern das Programm direkt abstürzt mit einem compiler-spezifischem Returncode.


                          > Und woher willst du wissen, dass das Ergebnis nicht genau INT_MAX ist und gar kein Überlauf aufgetreten ist? Erkennst du das dann als Fehler?

                          Indem man INT_MAX aus der Ergebnismenge ausschließt. Außerdem habe ich noch die Möglichkeit über errno genannt.

                          Bist du so hohl oder ist das Gehabe.

                          [
                          | Versenden | Drucken ]
                      1
                      Von phreck am Fr, 12. November 2010 um 16:28 #

                      Oh, und der Grund für undefiniertes Verhalten liegt nicht an der Banalität eines Statements, sondern eher u.a. darin, dem Compiler und den Library-Implementor mehr Freiheit beim Optimieren zu geben.

                      Bsp.: Dieser Artikel.

                      ---

                      Du kennst nicht viel außer C, oder? Und das nicht mal gut ...

                      [
                      | Versenden | Drucken ]
                      • 1
                        Von Trolly am Fr, 12. November 2010 um 16:37 #

                        Oh, und der Grund für undefiniertes Verhalten liegt nicht an der Banalität eines Statements, sondern eher u.a. darin, dem Compiler und den Library-Implementor mehr Freiheit beim Optimieren zu geben.
                        Wäre das dann nicht "implementation specific behaviour"?

                        Du kennst nicht viel außer C, oder? Und das nicht mal gut ...
                        Ad hominem? Das hätte ich jetzt nicht von dir erwartet.

                        [
                        | Versenden | Drucken ]
                        • 1
                          Von phreck am Fr, 12. November 2010 um 16:50 #

                          > Wäre das dann nicht "implementation specific behaviour"?

                          a) Sowohl als auch.
                          b) Das ist auch nicht viel besser wenn du portable Programme schreiben möchtest (wobei portabel schon die Kompatibilität deines Programmes zu gcc 4.4 und 4.5 bedeuten kann)

                          > Ad hominem? Das hätte ich jetzt nicht von dir erwartet.

                          Jemand, der Bugs mit Dummheit begründet, in einem Kontext, welcher den anderen signalisiert, er selbst sei dies nicht, sollte nicht die Wendung ad hominem benutzen.

                          [
                          | Versenden | Drucken ]
                          1
                          Von phreck am Fr, 12. November 2010 um 16:54 #

                          Sorry, muss mich wirklich mal registrieren, kein edit möglich.


                          Ich vermute deshalb, dass du nicht viel außer C kennst, weil es viele, viele Programmiersprachen gibt, die wohl definiert sind, sprich, die komplett ohne undefined behaviour auskommen. Beispiele: Haskell, C#, Java.

                          [
                          | Versenden | Drucken ]
          1
          Von RTFM 1993 am Fr, 12. November 2010 um 12:59 #

          @adope RTFM

          Habe ne manpage von 1993 gefunden, da stehts genauso drin:

          The memory areas should not overlap. Use memmove(3) if the memory areas do overlap.

          bei Adope ist Closed Source eh nur eine Strategie um schlecht geschriebenen Code zu verstecken ;)

          [
          | Versenden | Drucken ]
    2
    Von Samson am Fr, 12. November 2010 um 11:56 #

    ... a bug is a bug (ein fehler ist ein fehler) ... und sollte gefixt werden. unabhängig von der zweiten Feststellung mit der Performanz ...

    [
    | Versenden | Drucken ]
    2
    Von mrpi am Fr, 12. November 2010 um 11:58 #

    Wer eine Software mit einer solchen Verbreitung schreibt, von dem kann man durchaus erwarten, dass er diese Software mal mit Valgrind überprüft!
    Und gerade die Adobe Entwickler sollten auch mal einen Blick auf (k)cachegrind werfen, wenn man schonmal dabei ist.

    Wer sich auf undefiniertes Verhalten verlässt, der muss sich in C nunmal nicht wunden, wenn sich die Software ab einem undefiniertem Zeitpunkt undefiniert verhält.

    [
    | Versenden | Drucken ]
    2
    Von Lord am Fr, 12. November 2010 um 19:12 #

    Ich finde das was Linus da von sich gibt ist kompletter Unsinn, es kann nicht sein, dass Fehler nicht bereinigt werden dürfen nur um kompatibel zu alten Programmen zu sein.

    Wenn er jetzt behauptet, im Kernel würde sowas nie gemacht werden, dann scheint er wohl an Alzheimer zu leiden. Im Linuxkernel ist sowas permanent an der Tagesordnung. Oder wie sonst erklärt er den Umstand, dass Nvidia Treiber alle paar Kernelversion nicht mehr lauffähig sind, weil mal wieder eine Änderung im Kernel durchgeführt wurde.

    Selten so einen Blödsinn gelesen.

    [
    | Versenden | Drucken ]
    • 1
      Von DriverDevel am Fr, 12. November 2010 um 20:34 #

      > Selten so einen Blödsinn gelesen.

      Hätte ich da jetzt "dito" schreiben müssen? ;)

      Hier geht es beim Kernel um die Schnittstelle zum _Userspace_.
      Und die ist seit Jahrzehnten hoch-konstant, zumindest wenn man den Leuten Glauben schenken darf.

      Nvidia ist ein _Treiber_ und somit _Treiber_-Schnittstelle. Völlig andere Galaxie.

      [
      | Versenden | Drucken ]
    1
    Von Hugo Oguh am Fr, 26. November 2010 um 12:04 #

    Ich nicht. Das Streben nach Perfektion erlaubt es nicht, an dieser Stellen einen faulen Kompromiss zu machen und einen Fehler als Fehler belassen, nur weil Software deshalb funktioniert, weil es diesen Fehler gibt. Adobe ist es jetzt gefragt.

    Übrigens: Es gibt wesentlich wichtigere Anwendungen als Flash. Wenn es der XServer statt Flash wäre, wären die Entwickler wahrscheinlich ganz anders verfahren.

    Eigentlich kann man nur hoffen, dass dieser Flash-Unsinn endlich aufhört. Flash macht das WWW kaputt.

    [
    | Versenden | Drucken ]
1
Von Hans am Fr, 12. November 2010 um 11:39 #

Das prüfen auf fehlerhafte argumente in der glibc ist eigentlich fast unnötig, denn um solch einen fehler zu entdecken gibt es ja z.B. bereits valgrind. Wieso also in glibc diese funktion einbauen, die nur zu debugging zwecken vorhanden ist. Es wird ja auch nicht jeder speicherzugriff von der glibc geprüft (eben weil es einen geschwindigkeitsnachteil gibt)

[
| Versenden | Drucken ]
  • 1
    Von jjsa am Fr, 12. November 2010 um 13:46 #

    Das prüfen auf fehlerhafte argumente in der glibc ist eigentlich fast unnötig
    Klar es bringt ein wenig mehr Performance und vor allem öffnet ein Tür für absichtlich geschriebenen fehlerhaften Code.
    Wenn eine Überprüfung nicht statt findet kann durchaus ein Schadprogramme daraus profitieren.

    [
    | Versenden | Drucken ]
    • 1
      Von Hans am Fr, 12. November 2010 um 14:04 #

      Wenn du so ängstlich vor schadprogrammen bist, dann starte doch alle deine programme in valgrind. Nur leider macht das die meisten programme mehr oder weniger unbedienbar. Dafür hast du allerdings etwas mehr sicherheit.
      Oder soll jetzt glibc sämtliche arbeitsspeicher zugriffe checken, ob diese erlaubt sind? Wenn du erwartest, dass memcpy seine argumente überprüft, dann musst du auch erwarten, dass ALLE speicherzugriffe überprüft werden, weil nur so sichergestellt werden kann, dass alles ok ist. Dann wären wir aber wieder dort, dass du valgrind nehmen kannst, weil dort genau das gemacht wird ;)

      [
      | Versenden | Drucken ]
      • 1
        Von jjsa am Fr, 12. November 2010 um 17:27 #

        So ängstlich bin ich nicht. Meine Ausführung gilt eher Leute die unbedarft alles ausführen was Ihnen unter die Finger kommt.
        Wenn Windows so erfolgreich gehackt wird liegt es u. a. an ein zu Laschen Sicherheitskonzept.
        Für eigene Werke wird selbstverständlich Valgrind bemüht, ein kleinen Fehler kann sich immer bemerkbar machen. Ich habe ein Status Monitor für Epson Drucker programmiert, irgendwann habe ich die Benachrichtigung erhalten, dass der Anwender sich auf unerlaubte Weise Rechte verschaffen kann. Die Ursache war eigentlich nicht meinen Code aber ein fehlerhafte Bibliothek. Das Ergebnis ist, dass ich, um den Fehler zu beseitigen, das Environment untersuche und von unnötige Variable befreit und die Variablen die notwendig sind auf deren Inhalt untersuche und gegebenenfalls das Programm vorzeitig beendet. Wäre besagte Lib Fehlerfrei gewesen, hätte ich den Ärger nicht gehabt.

        [
        | Versenden | Drucken ]
1
Von Crass Spektakel am Fr, 12. November 2010 um 12:18 #

Auch wenns nie erlaubt war, besser jetzt einen zeitlich begrenzten Reverse Patch mit Warnung daß in sechs bis zwölf Wochen die Preussen scharf schiesen.

Aber naja, daß die glibc-Maintainer sturre Kommissköppe sind, das ist ja bekannt.

[
| Versenden | Drucken ]
  • 1
    Von Demon am Fr, 12. November 2010 um 12:29 #

    Auch wenns nie erlaubt war, besser jetzt einen zeitlich begrenzten Reverse Patch mit Warnung daß in sechs bis zwölf Wochen die Preussen scharf schiesen.

    Das wäre auch in meinen Augen eine saubere Lösung. Eine so fundamentale Änderung ohne eine vorherige Warnung durchzuführen, weil sie nun mal jetzt korrekt ist, halte ich persönlich für ein wenig zu extrem. Auch der Kernel hat schon Sachen grundlegend verändert, gab aber den Leuten immer Zeit, ihren Kram anzupassen.

    Dieser Beitrag wurde 1 mal editiert. Zuletzt am 12. Nov 2010 um 12:31.
    [
    | Versenden | Drucken ]
    1
    Von hjb am Fr, 12. November 2010 um 12:47 #

    Das dachte ich anfänglich auch, aber das wäre doch nicht praktikabel. Zumal die Adobe-Entwicker keinerlei Schüsse hören. Es ist schlicht ein Fehler (einer von Millionen in der Adobe-Software) und muss dort und nirgends sonst korrigiert werden.

    [
    | Versenden | Drucken ]
1
Von Pffft... am Fr, 12. November 2010 um 13:52 #

Nein, wir benutzen nicht memmove(), obwohl es 100% dasselbe Interface hat wie memcpy() und ohne weitere Prüfungen sicher funktioniert. Wir benutzen natürlich memcpy(), weil das ja 1% schneller ist. Und das brauchen wir, schließlich dürfen wir nicht einen Deut langsamer sein als die anderen, sonst gibt's Ärger mit dem Boss...

Und wenn's irgendwem um die Ohren fliegt? Wen interessiert das? Von denen hat doch eh keiner was bezahlt.

Kommerzielle Software war ein Haufen Dreck, ist ein Haufen Dreck und wird immer ein Haufen Dreck bleiben. Und wenn jemand über den Haufen Dreck stolpert, wird dieser eben zum Industriestandard erklärt und wer stolpert ist selbst schuld.

[
| Versenden | Drucken ]
1
Von ghj am So, 14. November 2010 um 14:18 #

Was macht denn memmove anders als memcpy?

[
| Versenden | Drucken ]
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung