Externe Bibliothek buggy?



  • int main()
    {
        EricRueckgabepufferHandle x = 0;
    
        assert(x == nullptr); // passt
        x = EricRueckgabepufferErzeugen();
        assert(x != nullptr); // passt
    
        EricRueckgabepufferHandle address = x;
        assert(x == address); // geht
        uint32_t s = EricRueckgabepufferLaenge(x);
        assert(x == address); // assertion nicht erfuellt
    
        return 0;
    }
    

    Ist dieses Verhalten für Windows und Linux ähnlich?

    Hast du mal Debug Tools ala Application Verifier bei Windows drübergejagt? Nach meinem Gefühl ist Windows manchmal etwas verschwiegen und undefiniert wenn es um Fehler geht.

    Vielleicht kommst du ja auch an die Speicherbereiche ran und kannst den Unterschied zwischen den Speicherbereichen und den Handles anschauen.

    Oder kann es sein dass die Funktion EricRueckgabepufferLaenge() einen unerwünschten Seiteneffekt hat? So nach dem Motto, dass die Funktion automatisch das Handle auf den nächsten Speicherbereich legt.

    EricRueckgabepufferHandle Handle = x;
    uint32_t s;
    
    while ((s = EricRueckgabepufferLaenge(x)) != INVALID_LENGTH)
    {
      // Ausgabe der Größe 
    }
    

    Notfalls pack die große Keule raus und wirf man einen kurzen Blick in das Disassembly von EricRueckgabepufferLaenge().



  • Mh, ich dachte auch erst, dass Windows mir den Fehler nur verschweigt, intern aber auch Probleme hat (oder sie einfach nicht bemerkt).

    Aber das Programm läuft unter Windows 1a. Die Speicheradressen bleiben gleich und nichts stürzt ab. Es wird sogar alles fein säuberlich aufgeräumt wie gewünscht. (Ich beziehe mich da auf mein letztes gepostetes Programm mit dem TEST-Makro)

    Mein Tipp ist eher, dass die Bibliothek keine Seiteneffekte* hat, sondern einfach nur ein groben Fehler vllt beid er Portierung nach linux hat, die den gesamten Stack korrumpiert, da mir sämtliche Stackvariablen zerschossen und mehr doer weniger willkürlich verändert werden.

    *: Ich dachte auch erst an einen undokumentierten Seiteneffekt, der meinen Zeiger um z.B. die Puffergröße weiter schiebt (also quasi an das Ende hinter den Puffer wie einen EndIterator), aber da müsste ich durch Pointerarithmetik ja etwa sehen können wie die Zeiger stehen, aber die Werte sind teilweise mehrere hunderttausende Speicherzellen distanziert.

    Idee: Am Montag teste ich das mal mit Globalen statt Stackvariablen.



  • Skym0sh0 schrieb:

    Mein Tipp ist eher, dass die Bibliothek keine Seiteneffekte* hat, sondern einfach nur ein groben Fehler vllt beid er Portierung nach linux hat, die den gesamten Stack korrumpiert, da mir sämtliche Stackvariablen zerschossen und mehr doer weniger willkürlich verändert werden.

    Ich gehe eher davon aus dass es hier ein Problem mit der ABI gibt.
    Also dass die Linux-LIB mit nem anderen Compiler bebaut wurde, andere Calling-Conventions verwendet oder sowas in der Art.
    Und dass dadurch der Stack zerschossen wird.



  • hustbaer schrieb:

    Skym0sh0 schrieb:

    Mein Tipp ist eher, dass die Bibliothek keine Seiteneffekte* hat, sondern einfach nur ein groben Fehler vllt beid er Portierung nach linux hat, die den gesamten Stack korrumpiert, da mir sämtliche Stackvariablen zerschossen und mehr doer weniger willkürlich verändert werden.

    Ich gehe eher davon aus dass es hier ein Problem mit der ABI gibt.
    Also dass die Linux-LIB mit nem anderen Compiler bebaut wurde, andere Calling-Conventions verwendet oder sowas in der Art.
    Und dass dadurch der Stack zerschossen wird.

    Ich habe auch schon in die Richtung 32Bit Lib/64Bit Toolchain o.ä. gedacht.
    Nach allem, was ich lese ist ERiC nur für 32Bit-OS freigegeben.



  • Ja, da habt ihr Recht. Und ich habe die Probleme auf einem 64Bit Ubuntu.
    Aber der GCC kann doch nach 32Bit kompilieren, per -m32 ?!
    Sonst gabs auf jedenfall immer Fehlermeldungen, dass die Bibliotheken nicht passend seien.



  • Sag mal du hast doch sicher Header für die Lib, oder? Zeig mal eine der Headerfunktionen. Da steht bestimmt eine normale Deklaration alla

    void foo();
    

    Das würde für den Compiler bedeuten, dass er sich eine Callingconvention aussuchen/ausdenken darf.
    Stattdessen solltest du eine Deklaration haben, die die Callingconvention festlegt:

    extern "C"{
    __attribute__((stdcall)) void foo();
    };
    

    Dann noch als 32-Bit und es sollte funktionieren.



  • Ja, ich poste das am Montag mal.



  • So, hier ist mal eine gekürzte Header-Datei. Gekürzt deshalb, weil da viele Kommentare drinstehen und das über mehrere Hundert Zeilen:

    #ifdef __cplusplus
    extern "C"
    {
    #endif
        // ...
        ERICAPI_DECL EricRueckgabepufferHandle STDCALL EricRueckgabepufferErzeugen();
    
        ERICAPI_DECL const char* STDCALL EricRueckgabepufferInhalt(EricRueckgabepufferHandle handle);
    
        ERICAPI_DECL uint32_t STDCALL EricRueckgabepufferLaenge(EricRueckgabepufferHandle handle);
    
        ERICAPI_DECL int STDCALL EricRueckgabepufferFreigeben(EricRueckgabepufferHandle handle);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /*ERICAPI_C_H_*/
    

    Das STDCALL ist derzeit definiert als nichts. Wenn meine IDE nichts ganz so suaber ist, jedoch maximal als:

    __attribute__((__stdcall__))
    

    Das ERICAPI_DECL ist definiert als:

    #ifndef ERICAPI_DECL
    #define ERICAPI_DECL ERIC_DECL_EXPORT
    #endif
    

    mit:

    __attribute__((visibility("default")))
    


  • Skym0sh0 schrieb:

    Das STDCALL ist derzeit definiert als nichts.

    Vielleicht ist genau das das Problem.



  • hustbaer schrieb:

    Skym0sh0 schrieb:

    Das STDCALL ist derzeit definiert als nichts.

    Vielleicht ist genau das das Problem.

    😮 Ja, das sieht so aus. Mein Testprogramm läuft nun fehlerfrei durch. Ich gucke gerade am richtigen Code, ob der auch nicht abstürzt oO

    Ja sieht gut aus. Danke Jungs !

    problem: Der Bugreport ist raus 😞


Anmelden zum Antworten