Externe Bibliothek buggy?
-
Ja, die Idee kam mir mittlerweile auch. Das probiere ich jetzt.
Aber andererseits, wieso stürzt das Programm dann ab, wenn die size > 0 ist und der Puffer gefüllt ist?
Edit: Also hustbaers Idee ist probiert. Die Längenabfrage rettet mich in Fällen, wo die Größe tatsächlich 0 ist.
Das Problem bleibt jedoch: sind sinnvolle Dinge in den Rückgabepuffer geschrieben und die Länge damit > 0 (in meinem Fall knapp 115000 Zeichen), dann crasht es nach dem Pufferzugriff.
-
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; }o_O
Muss ich mehr zu der Bibliothek sagen?
-
Hast du mal geprüft, ob die calling-conventions stimmen? Crash bei return hört sich schwer danach an.
-
mh, laut Header Dateien STDCALL, was beim GCC als nichts definiert ist.
Ich habe auch nichts andere definiert, oder liege ich da falsch?Ich setzte sogar noch ein Progrämmchen drauf:
#include <cassert> #include <iostream> //----------------------------------------------- #include <ericapi.h> #include <tm98ericapi.h> #include <ericdef.h> #include <eric_types.h> #include <eric_fehlercodes.h> //----------------------------------------------- void test(const char* file, int line, long first, long second) { std::cout << "File: \"" << file << "\", Zeile: \"" << line << "\" -> " << first << " = " << second << std::endl; assert(first == second); } #define TEST(a, b) { test(__FILE__, __LINE__, (long)(a), (long)(b)); } //----------------------------------------------- int main() { EricRueckgabepufferHandle x = 0; assert(x == nullptr); x = EricRueckgabepufferErzeugen(); assert(x != nullptr); const EricRueckgabepufferHandle address = x; TEST(x, address); int r = EricVersion(x); assert(r == ERIC_OK); TEST(x, address); const char* ptr = EricRueckgabepufferInhalt(x); TEST(x, address); uint32_t s = EricRueckgabepufferLaenge(x); TEST(x, address); return 0; }Ausgabe:
File: "../src/bugtest.cpp", Zeile: "26" -> 152551504 = 152551504 File: "../src/bugtest.cpp", Zeile: "31" -> 152551504 = 0 File: "../src/bugtest.cpp", Zeile: "35" -> 0 = 0 File: "../src/bugtest.cpp", Zeile: "39" -> 0 = -146141184
-
Probier mal
#define STDCALL __attribute__((stdcall))
-
Nein, hilft auch nicht. Zumal bei meinen aktuellen Miniprogrammen nichtmals ein Funktionsaufruf vonstatten geht, ausser zu der Lib hin.
-
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 #endifmit:
__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 oOJa sieht gut aus. Danke Jungs !
problem: Der Bugreport ist raus
