Anzeige:
Ergebnis 1 bis 9 von 9

Thema: Fehler in gcc oder Electric Fence?

  1. #1
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650

    Fehler in gcc oder Electric Fence?

    Beim Debugen ist mir aufgefallen, dass dieses minimale C-Programm

    Code:
    #include <assert.h>
    #include <math.h>
    #include <string.h>
    #include <setjmp.h>
    #include <stdio.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <time.h>
    #include <signal.h>             // signals
    
    int
    main (int argc, char *argv[])
    {
      char line[100000][256] = { {'\0'} };
      return (0);
    }
    korrekt läuft, wenn es ohne Electric Fence compiliert wird, aber mit Electric Fence, konkret

    gcc -O3 -D__SMP__ -D_REENTRANT -lm -lz -Wall -pedantic -ggdb -lefence -o error0 error0.c

    liefert es nur "Speicherzugriffsfehler".
    Insight meldet nur "Cannot insert breakpoint 1:" und gdb meldet
    "Warning:
    Cannot insert breakpoint -2.
    Error accessing memory address 0x4000bb50: Eingabe-/Ausgabefehler.
    The same program may be running in another process. "

    Ist das ein Fehler im gcc oder im Electric Fence?

  2. #2
    Registrierter Benutzer
    Registriert seit
    24.06.2003
    Beiträge
    486
    Also an EFence kann es nicht liegen,weil EFence nur malloc/free und Co. überschreibt,also mit dynamischer Allokierung zutun hat.
    Hier haben wir es aber mit dem Stack zu tun,und dein Beispiel Seg-fault bei mir auch (ohne EFence).Mach das Array kleiner,oder allokiere es zur Laufzeit,es ist zu groß für den Stack.

  3. #3
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    Aha, aber standard-konform ist das nicht und merkwürdig ist ja, dass es ohne efence funktioniert. Mit 100.000 Zeilen von je 256 Zeichen habe ich es aber noch nicht getestet.

  4. #4
    Registrierter Benutzer
    Registriert seit
    24.06.2003
    Beiträge
    486
    Original geschrieben von nobody0
    Aha, aber standard-konform ist das nicht
    Hmm?Was meinst du jetzt konkret damit?

    und merkwürdig ist ja, dass es ohne efence funktioniert.
    Glückssache würde ich sagen.
    Auf drei getesteten Compilern schmiert dieser Code zur Laufzeit ab
    Code:
    int main() {
        char line[100000][256];
    }
    außer,es ist die Optimierung nach ganz oben gedreht,und das Array wird wegoptimiert,dann nicht.
    Naja,eine Warnung zur Compiletime wäre mir auch lieber.

  5. #5
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    Original geschrieben von wraith
    Hmm?Was meinst du jetzt konkret damit?
    Ganz einfach: Wenn ich ein zweidimensionales Feld wie oben anlege, dann wird damit automatisch Speicher alloziert, so wie z. B. mittels
    int i = 0;
    (zumindest nach ANSI-C)! Und wenn alle Elemente mit einem Wert initialisiert werden, dann stehen n*m dieser Werte im Speicher; da gibt es keinen Grund abzuschmieren!

    Wie mir nachträglich eingefallen ist, gab es mit dem gcc schon vor Jahren das Problem, dass Felder über 2 MB nicht oder nicht richtig angelegt wurden und es auch mit -Wall -pedantic nicht einmal eine Warnung gab! Bei einem 512 MB großen Feld war mir das aufgefallen und als Workaround um diesen Bug musste ich mit Pointern u. mit malloc arbeiten. Ich hatte das kurzzeitig vergessen, weil ich annahm, dass dieser Bug längst beseitigt ist, aber der ist ja immer noch drinn und auch immer ohne warning!!!
    Da werde ich wohl einen Bug-Report schreiben müssen.

    Dabei habe ich extra Felder fester Länge zur Limitierung verwendet um Fehler möglichst auszuschließen und nun muss ich wieder einen Workaround wegen diesem alten Compiler-Bug schreiben
    Geändert von nobody0 (24-08-2003 um 18:17 Uhr)

  6. #6
    Registrierter Benutzer
    Registriert seit
    24.06.2003
    Beiträge
    486
    Original geschrieben von nobody0
    Ganz einfach: Wenn ich ein zweidimensionales Feld wie oben anlege, dann wird damit automatisch Speicher alloziert, so wie z. B. mittels
    int i = 0;
    (zumindest nach ANSI-C)! Und wenn alle Elemente mit einem Wert initialisiert werden, dann stehen n*m dieser Werte im Speicher; da gibt es keinen Grund abzuschmieren!
    Ja,das hat mit Ansi C aber wenig bis nichts zutun,und ist auch kein Bug im gcc.
    Es geht einfach um die Größe des Runtime-Stacks,die man auch mit irgendeiner Option erhöhen kann.
    Es gibt keine Garantie,daß ein Feld von beliebiger Größe auf dem Stack Platz findet (im Standard gibt es den Begriff Stack nichtmal),genauso wenig wie es eine Garantie gibt,daß man ein dynamisches Feld beliebiger Größe auf dem Heap erstellen kann (auch einen Heap gibt es nicht im Standard).
    Das ist alles abhängig vom OS und vom Compiler,darum hab' ich auch deinen Einwand mit standard konform nicht verstanden.

    wegen diesem alten Compiler-Bug
    Nochmal,es ist kein Compiler Bug,wie oben geschrieben,hab' ich es auf drei Compilern getestet (aktuellen != gcc Compilern),die werden wohl nicht alle den selben Bug haben .

    Edit:Mit ulimit -a kannst du sehen,wie groß der Stack ist.
    Geändert von wraith (24-08-2003 um 19:01 Uhr)

  7. #7
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    Naja, es sollte aber zumindest eine Warnung geben, denn ulimit -a zeigt mir unlimited bei stack size, aber praktisch ist es winzig, gemessen an den 2 GB RAM. Und mit malloc u. Pointer funktionert es ja; den Bug gäbe es nicht, wenn arrays damit realisiert wären!
    Gibt es denn keine libraries, die genau das machen?

  8. #8
    Registrierter Benutzer
    Registriert seit
    24.06.2003
    Beiträge
    486
    Warum willst du überhaupt soviel Speicher auf dem Stack allokieren?

    Original geschrieben von nobody0

    Gibt es denn keine libraries, die genau das machen?
    Wenn du auch C++ in Betracht ziehst,dann gibt es genug Möglichkeiten.
    Ein std::vector macht genau das was du willst.
    Wenn du bei C bleiben willst,dann mußt du ebend mit malloc selber ran.Ist ja keine große Sache,nur das Aufräumen nachher nicht vergessen.

    Du könntest das Array auch static deklarrieren,aber dann bleibt der Speicher auch noch nach dem Funktionsaufruf erhalten.

  9. #9
    Registrierter Benutzer
    Registriert seit
    22.03.2001
    Beiträge
    650
    Aha, mit static funktioniert es; zumindest meldet efence nun nichts mehr.
    Wieso funktioniert es denn mit static und ohne nicht?

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •