Merkwürdige Crashes bei C++ Code unter Linux (illegal free bei std::string)



  • Hi,

    ich habe merkwürdige Crashes unter Linux, wenn ein std::string gelöscht wird.
    Kompiliere ich den selben Code unter AIX, sehe ich diese Probleme nicht.

    Ich habe ein Testprogramm von SAP, das einen Treiber, den ich schreibe, zertifizieren soll. Wenn dieses Programm das shared object lädt und die Testsuite ausführt, bekomme ich lauter "illegal free" exceptions von glibc. UNter Windows und AIX bekomme ich diese nicht.

    Simples Codebeispiel:

    std::string bla = "huhu";
    bla += "haha";
    

    Dieser Code führt zum Absturz.
    Ändere ich die Zeilen jedoch in

    std::string bla("huhu");
    bla.append("haha");
    

    um, dann funktioniert es ohne Probleme. Ich habe irgendwo einmal gelesen, das der Copy Constructor eventuell daran Schuld sein kann, und ja, zumindest bei mir scheint der Workaround auch super zu funktionieren:

    http://stackoverflow.com/questions/751940/problem-with-containers-glibc-detected-free-invalid-pointer-0x41e0ce

    Kann mir mal jemand erklären, was das Problem sein könnte? Könnte es an dem SAP-Testprogramm liegen, das irgendwie eine static gelinkte glibc nutzt, die string Allokation anders behandelt? Oder kann ich mit einem simplen Compileflag diesen Fehler beheben?

    Dieser Code ist von einem alten Projekt, das ich nun portieren soll. Aber es kann doch nicht sein, dass ich nun überall copy ctors vermeiden muss, damit das Stringhandling funktioniert?

    Irgendwie verstehe ich das Problem nicht so ganz.



  • TheGrudge schrieb:

    Simples Codebeispiel:

    std::string bla = "huhu";
    bla += "haha";
    

    Dieser Code führt zum Absturz.

    Ich nehme mal an, dass dieser Code für sich allein genommen nicht zum Absturz führt. Wenn doch, ist der Compiler kaputt.

    Der Fehler liegt aber ziemlich sicher an anderer Stelle im Programm. Die Ursache für sowas ist quasi immer ein kaputter Heap, der durch Schreiben in unzulässige Speicherbereiche zerschossen wurde. Zum Beispiel wenn man über die Grenzen eines Arrays hinweg schreibt.
    Dass sich der Fehler ausgerechnet bei Zerstörung des Strings äußert, ist bloß Zufall.

    valgrind hilft, solche Fehler aufzuspüren.



  • TheGrudge schrieb:

    Ich habe ein Testprogramm von SAP, das einen Treiber, den ich schreibe, zertifizieren soll. Wenn dieses Programm das shared object lädt und die Testsuite ausführt, bekomme ich lauter "illegal free" exceptions von glibc.

    Übersetzt du das Testprogramm selber oder liegt es dir nur als Binary vor? Wenn nicht die gleichen Compilerversionsstände verwendet werden, könnte dein Fehler dabei entstahen.



  • TheGrudge schrieb:

    Könnte es an dem SAP-Testprogramm liegen, das irgendwie eine static gelinkte glibc nutzt, die string Allokation anders behandelt?

    Ich kenne mich mit Linux (SOs etc.) nicht wirklich aus, aber ich schätze das Problem könnte sein, dass das SAP-Testprogramm mit ner anderen GCC Version compiliert wurde als dein "Treiber".



  • Nein, ich kann es nicht selber kompilieren, es liegt nur im Binaryformat vor.
    Dennoch verstehe ich nicht ganz, wieso die Version ohne Copy Ctor funktioniert. Sind denn der copy ctor und der normale ctor so sehr unterschiedlich beim std::string?



  • Ich sehe in beinem Beispiel keinen Aufruf eines Copy-Ctors.

    Aber darum geht's nicht. Es kann einfach Probleme machen wenn unterschiedliche Library Versionen (Standard-Library, glibc, ...) "gemischt" werden. Normalerweise sollte das durch Versionierung der Shared-Objects abgefangen werden. Praktisch habe ich damit aber keine Erfahrung, da ich mich mit Linux wie gesagt nicht wirklich auskenne.

    Und was überhaupt gar nicht gehen kann: wenn zwei Programmteile miteinander über ein Interface kommunizieren welches z.B. std::string verwendet (oder eine andere in der C++ Standard Library definierte Klasse/Template). Wenn in so einem Fall nicht beide mit der selben C++ Standard Library compiliert wurden, dann knallt es irgendwann irgendwo, ganz egal was wo versioniert wird.



  • Ich würde an deiner Stelle wirklich mal valgrind benutzen. Ist einfacher als ins blaue zu Raten und wird sicher die eine oder andere Überraschung noch bringen.
    Tritt das Problem eigentlich generell auf oder nur bei Strings, die du in dem Programm und dem SO-File nutzt?



  • Nein, das ist kein generelles Problem, sondern nur wenn ich Strings im so mit dem Testprogramm benutze. Aber gute Idee, werde morgen mal auf der Arbeit valgrind installieren.



  • Ich würde mal raten, dass beide Teile unterschiedliche Laufzeit-Bibliotheken nutzen und damit mit verschiedenen Allokatoren arbeiten. Du musst dann also mit einem Allokator arbeiten, der vom Testprogramm bereit gestellt wird. Oder vermeiden, dass der andere Programmteil auf die Idee kommt deinen Speicher frei zugeben.


Log in to reply