libffi => Segmentation Fault
-
freiwilliger tester schrieb:
Also bei mir läuft da alles.
Das wundert mich nichtmals sonderlich, denn immerhin ist das das Beispielprogramm für FFI. Es gibt also Hoffnung, dass die das auch mal lauffähig hatten.
freiwilliger tester schrieb:
XXX% uname -a Linux XXX 2.6.37-1-686 #1 SMP Tue Feb 15 18:21:50 UTC 2011 i686 GNU/Linux
Mich mach aber der
reinterpret_cast
stutzig, ich bin nicht sicher, ob das erlaubt ist.Zum einen läuft's bei dir, was immerhin schonmal aussagt, dass der Cast nicht falsch ist.
Zum anderen ist er erforderlich, weil das umcasten einer von int (*)(char const ) nach void()(void) nunmal notwendig ist, um die Funktion übergeben zu können, ohne dass der Compiler meckert. ^^Vielen Dank für's ausprobieren. Du benutzt mit dem i686 einen 32-Bitter, wenn ich das richtig in Erinnerung habe. Also damit einen anderen Part der libffi. Wäre blöd, wenn der 64-Bit-Part der libffi kaputt wäre, aber aufgrund des Null-Pointerzugriffs innerhalb der libffi und der Tatsache, dass ich bisher auch nix besseres gefunden habe, befürchte ich das gerade auch.
Vielen Dank für Dein Feedback! Hätten wir noch jemanden mit einer 64-Bit CPU?
Edit: Quotetags korrigiert
-
Ich hab's jetzt auch mal probiert.
's läuft, wenn ich die Bemerkungman ffi_call schrieb:
rvalue must point to storage that is sizeof(long) or larger.
For smaller return value sizes, the ffi_arg or ffi_sarg integral type must be used to hold the return value.ernst nehme und für definiere:
ffi_arg rc;
.
Evtl. war's das schon, aber dazu muesste man sicherlich noch ein bisschen lesen...pS:
uname -a Linux sinsemilla 3.5.7 #3 SMP Mon Oct 22 08:36:28 CEST 2012 x86_64 AMD Athlon(tm) 64 X2 Dual Core Processor 5600+ AuthenticAMD GNU/Linux
-
Furble Wurble schrieb:
Ich hab's jetzt auch mal probiert.
's läuft, wenn ich die Bemerkungman ffi_call schrieb:
rvalue must point to storage that is sizeof(long) or larger.
For smaller return value sizes, the ffi_arg or ffi_sarg integral type must be used to hold the return value.ernst nehme und für definiere:
ffi_arg rc;
.
Evtl. war's das schon, aber dazu muesste man sicherlich noch ein bisschen lesen...Leider gibt's bei mir keine Warning, die ich lesen könnte - das Programm kompiliert bei mir ohne irgendwelchen Kommentar (gcc 4.7.2) - und das ist eigentlich auch das einführende Beispiel zu der Lib. ^^
Offensichtlich ist es nicht mehr sonderlich aktuell.Vielen Dank, Du hast mir sehr geholfen, denn es läuft nun.
Edit: puts liefert also offenbar auf der 64-Bit-Maschine ein 64-Bit Integer zurück, womit ich mir vermutlich args überschreibe...
Ich habe mal eine 2. Integervariable dahinter gepackt, sie mit 4711 initialisiert und wie erwartet ist sie nach dem ersten Auruf fälschlicherweise mit 0 überschrieben.
Das ist im Nachhinein logisch, aber laut der Referenz von cplusplus.com unerwartet, ich hatte puts() auch noch nicht mit 64-Bit Rückgabe wahrgenommen. Das erklärt dann auch, wieso es auf 32 Bit keine Probleme gab.
-
Sollte man nicht eigentlich auch statt dem reinterpret cast ein
func funcptr = FFI_FN( puts );
verwenden?
-
Was für ein Albtraum. Typsicherheit gleich Null. Gefahr, sich in den Fuß zu schießen: Extrem hoch.
In C++ kann man das sicherlich auch eleganter lösen.
Was ist eigentlich das Problem, was du mit libffi zu lösen versuchst?
-
Xin schrieb:
Edit: puts liefert also offenbar auf der 64-Bit-Maschine ein 64-Bit Integer zurück, womit ich mir vermutlich args überschreibe...
Ich habe mal eine 2. Integervariable dahinter gepackt, sie mit 4711 initialisiert und wie erwartet ist sie nach dem ersten Auruf fälschlicherweise mit 0 überschrieben.
Das ist im Nachhinein logisch, aber laut der Referenz von cplusplus.com unerwartet, ich hatte puts() auch noch nicht mit 64-Bit Rückgabe wahrgenommen. Das erklärt dann auch, wieso es auf 32 Bit keine Probleme gab.
Ist es nicht eher so, dass `void
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);`
einen Typen der Größe
<=sizeof(long)
an die Stellervalue
schreibt. Und wenn dort der Platz nicht reicht es kracht?
Alsoputs()
ist wohl gänzlich unschuldig...
-
Shade Of Mine schrieb:
Sollte man nicht eigentlich auch statt dem reinterpret cast ein
func funcptr = FFI_FN( puts );
verwenden?Keine Ahnung... wie gesagt... ich versuche das erste und einzige Beispielprogramm der mitgelieferten Doku zu anzugehen.... Unter Linux bekommt man ja freundlicherweise noch die Man-Pages dazu.
Ansonsten ist
/* Useful for eliminating compiler warnings */ #define FFI_FN(f) ((void (*)(void))f)
Im Vergleich zum reinterpret_cast auch nicht so der Bringer... bitte keine Diskussion darüber, dass man FFI_FN suchen könnte... Ich versuche mich in die libffi einzuarbeiten, ich versuche hier nicht als libffi-Profi den perfekten Code zu präsentieren.
krümelkacker schrieb:
Was für ein Albtraum. Typsicherheit gleich Null. Gefahr, sich in den Fuß zu schießen: Extrem hoch.
In C++ kann man das sicherlich auch eleganter lösen.
Was ist eigentlich das Problem, was du mit libffi zu lösen versuchst?
Ich möchte eine Funktion aus einer fremden Bibliothek rufen. Nur weiß ich halt zur Kompilierzeit weder welche Library, noch welche Funktion, noch welche Parameter.
Furble Wurble schrieb:
Ist es nicht eher so, dass `void
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);`
einen Typen der Größe
<=sizeof(long)
an die Stellervalue
schreibt. Und wenn dort der Platz nicht reicht es kracht?
Alsoputs()
ist wohl gänzlich unschuldig...int ist doch kleiner gleich als sizeof(long).
Beispielprogramm... ^^
Ich versuche nicht Antworten zu liefern, sondern ich versuche das Beispielprogramm mit seinen Macken nachzuvollziehen. Das Beispielprogramm ist aber nicht von mir, sondern demonstriert wie die libffi funktioniert - oder halt nichtAnsonsten... hat jemand Erfahrung damit, die libffi unter Windows gängig zu bekommen?
-
Xin schrieb:
Furble Wurble schrieb:
Ist es nicht eher so, dass `void
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);`
einen Typen der Größe
<=sizeof(long)
an die Stellervalue
schreibt. Und wenn dort der Platz nicht reicht es kracht?
Alsoputs()
ist wohl gänzlich unschuldig...int ist doch kleiner gleich als sizeof(long).
Ja. Aber wenn nur
sizeof(int)
bytes da sind kann man u.U. keinen long dorthin schreiben. So ungefähr läuft es ab:#include <cstdio> #include <iostream> #include <iomanip> void puts_wrapper(void *result){ *(long*)result = std::puts("Ich gebe einen int zurueck, aber an *result wird ein long geschrieben! :)"); } int main(){ int result, sentry = 0xdeadbeef; std::cout << "Jetzt bin ich da: " << std::hex << sentry << '\n'; puts_wrapper(&result); std::cout << "Jetzt bin ich weg: " << std::hex << sentry << '\n'; }
Jetzt klar, was ich meine?
-
Xin schrieb:
krümelkacker schrieb:
Was ist eigentlich das Problem, was du mit libffi zu lösen versuchst?
Ich möchte eine Funktion aus einer fremden Bibliothek rufen. Nur weiß ich halt zur Kompilierzeit weder welche Library, noch welche Funktion, noch welche Parameter.
Und wo wird das festgelegt, was wie aufgerufen werden soll? Wer ruft ffi_prep_cif auf? Wo kommt die Functionsadresse her?
-
Furble Wurble schrieb:
Jetzt klar, was ich meine?
Ja... interessant...
Super! Und nochmals besten Dank.Kann man Dich irgendwo direkt erreichen? Sofern Du Dich von mir nerven lassen magst.
FFI in Kombination Windows flutschen Dir nicht zufällig auch aus dem Ärmel?krümelkacker schrieb:
Und wo wird das festgelegt, was wie aufgerufen werden soll? Wer ruft ffi_prep_cif auf? Wo kommt die Functionsadresse her?
Mein Programm wird entsprechend konfiguriert und ruft sämtliche FFI-Funktionen.
Betriebssystemabhängig gibt es Möglichkeiten dynamisch linkbare Bibliotheken zur Laufzeit zu laden und die Funktionspointer zu erfragen.
-
Xin schrieb:
Furble Wurble schrieb:
Jetzt klar, was ich meine?
Ja... interessant...
Super! Und nochmals besten Dank.Kann man Dich irgendwo direkt erreichen? Sofern Du Dich von mir nerven lassen magst.
FFI in Kombination Windows flutschen Dir nicht zufällig auch aus dem Ärmel?Nein. Ich habe auch heute das erste mal von ffi gehört...
Aber bei weiteren Problemen lese ich hier im Forum ja ständig mit. :xmas2:
-
Furble Wurble schrieb:
Xin schrieb:
FFI in Kombination Windows flutschen Dir nicht zufällig auch aus dem Ärmel?
Nein. Ich habe auch heute das erste mal von ffi gehört...
Aber bei weiteren Problemen lese ich hier im Forum ja ständig mit. :xmas2:*lach*, okay. ^^
Hast Du eine besonders gute Doku dazu gefunden oder Dir mal eben spaßeshalber den Quelltext davon reingezogen?
Ich habe nämlich bisher verhältnismäßig wenig (funktionierendes) zu dem Thema gefunden.
-
Xin schrieb:
Furble Wurble schrieb:
Xin schrieb:
FFI in Kombination Windows flutschen Dir nicht zufällig auch aus dem Ärmel?
Nein. Ich habe auch heute das erste mal von ffi gehört...
Aber bei weiteren Problemen lese ich hier im Forum ja ständig mit. :xmas2:*lach*, okay. ^^
Hast Du eine besonders gute Doku dazu gefunden oder Dir mal eben spaßeshalber den Quelltext davon reingezogen?
Ich habe nämlich bisher verhältnismäßig wenig (funktionierendes) zu dem Thema gefunden.Sowohl als auch...tatsächlich habe ich die man pages, die Header - und irgendwo hier schlummern auch die Quelltexte (Gentoo Linux).
Allerdings war die erste Dokumentation, die ich erhalten habe die Google Anfrage: ffi_call man pageSchien mir die erste Anlaufstelle.
-
Xin schrieb:
krümelkacker schrieb:
Und wo wird das festgelegt, was wie aufgerufen werden soll? Wer ruft ffi_prep_cif auf? Wo kommt die Functionsadresse her?
Mein Programm wird entsprechend konfiguriert und ruft sämtliche FFI-Funktionen.
Betriebssystemabhängig gibt es Möglichkeiten dynamisch linkbare Bibliotheken zur Laufzeit zu laden und die Funktionspointer zu erfragen.Hmm ... wenn zur Laufzeit erst feststeht, was wie aufgerufen werden soll (per Konfigurationsdatei oder Benutzereingabe) dann sehe ich auch nicht, wie man es anders machen könnte. Wo braucht man das? Baust du einen Scriptsprachen-Interpreter, der über solche Konfigurationsdateien beliebige C-Funktionen aufrufen können soll? Nur der Neugier wegen gefragt.
-
krümelkacker schrieb:
Hmm ... wenn zur Laufzeit erst feststeht, was wie aufgerufen werden soll (per Konfigurationsdatei oder Benutzereingabe) dann sehe ich auch nicht, wie man es anders machen könnte. Wo braucht man das? Baust du einen Scriptsprachen-Interpreter, der über solche Konfigurationsdateien beliebige C-Funktionen aufrufen können soll? Nur der Neugier wegen gefragt.
Ich wüsste derzeit auch keine andere Verwendung für eine solche Lib als interpretierbare Skripts.
Das erklärt vermutlich, weshalb die vorhandene Doku eher überschaubar erscheint: Damit beschäftigt man sich ein paar Tage, dann läuft das und dann macht man mit anderen Dingen weiter.
Und der Bedarf Skriptsprachen beizubringen, C-Funktionen zu rufen, ist ja auch nicht alltäglich.