2010-05-06 3 views
12

Bei der Entwicklung einer SWIG-Wrapped-C++ - Bibliothek für Ruby stießen wir auf einen unerklärlichen Absturz bei der Ausnahmebehandlung innerhalb des C++ - Codes.segfault während __cxa_allocate_exception in SWIG-Wrapped-Bibliothek

Ich bin nicht sicher über die spezifischen Umstände, um das Problem neu zu erstellen, aber es geschah zuerst während eines Anrufs zu std::uncaught_exception, dann nach ein paar Codeänderungen, verschoben zu __cxa_allocate_exception während der Konstruktion der Ausnahme. Weder GDB noch Valgrind gaben einen Einblick in die Ursache des Absturzes.

Ich habe mehrere Verweise auf ähnliche Probleme gefunden, einschließlich:

Das übergeordnete Thema scheint eine Kombination aus zu sein Umstände:

  • AC Anwendung auf mehr als eine C++ Bibliothek
  • Mehr als eine Version von libstdc verbunden ++ verwendet wurde während der Kompilierung
  • Im Allgemeinen ist die zweite Version von C++ verwendet wird, stammt aus einer binär nur Implementierung von libGL
  • Das Problem tritt nicht auf, wenn Ihre Bibliothek mit einer C++ Anwendung zu koppeln, nur mit einer C-Anwendung

Die „Lösung“ ist ausdrücklich Ihre Bibliothek libstdC++ zu verknüpfen und möglicherweise auch mit libGL, Erzwingen der Reihenfolge der Verknüpfung.

Nachdem ich viele Kombinationen mit meinem Code versucht habe, ist die einzige Lösung, die ich gefunden habe, die LD_PRELOAD="libGL.so libstdc++.so.6" ruby scriptname Option. Das heißt, keine der Kompilierungszeit-Verknüpfungslösungen machte einen Unterschied.

Mein Verständnis des Problems ist, dass die C++ - Laufzeit nicht ordnungsgemäß initialisiert wird. Indem Sie die Reihenfolge des Linkens erzwingen, starten Sie den Initialisierungsprozess und es funktioniert. Das Problem tritt nur bei C-Anwendungen auf, die C++ - Bibliotheken aufrufen, da die C-Anwendung selbst nicht mit libstdC++ verknüpft ist und die C++ - Laufzeit nicht initialisiert. Da SWIG (oder boost :: python) eine gängige Methode zum Aufrufen einer C++ - Bibliothek aus einer C-Anwendung ist, kommt SWIG häufig bei der Problemforschung vor.

Gibt es jemanden, der mehr Einblick in dieses Problem geben kann? Gibt es eine tatsächliche Lösung oder gibt es nur Workarounds?

Danke.

+0

Die tatsächliche Ursache des Problems gefunden. Hoffentlich hilft das jemand anderem, diesen Fehler zu finden. Wahrscheinlich haben Sie irgendwo statische Daten, die nicht richtig initialisiert werden. Wir haben es getan, und die Lösung war im Boost-Log für unsere Code-Basis. https://sourceforge.net/projects/boost-log/forums/forum/710022/topic/3706109. Das eigentliche Problem ist die verzögerte geladene Bibliothek (plus Statik), nicht die möglicherweise mehrere Versionen von C++ aus verschiedenen Bibliotheken. Für weitere Informationen: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.13 – lefticus

+2

Sie sollten dies in eine Antwort kopieren, damit andere es einfacher sehen können. –

Antwort

5

Michael Dorgan Vorschlag folgend, ich bin Kopieren meines Kommentars in eine Antwort:

die eigentliche Ursache des Problems gefunden. Hoffentlich hilft das jemand anderem, diesen Fehler zu finden. Wahrscheinlich haben Sie irgendwo statische Daten, die nicht richtig initialisiert werden. Wir haben es getan, und die Lösung war im Boost-Log für unsere Code-Basis. https://sourceforge.net/projects/boost-log/forums/forum/710022/topic/3706109. Das eigentliche Problem ist die verzögerungsgeladene Bibliothek (plus Statik), nicht die potentiell mehrere Versionen von C++ aus verschiedenen Bibliotheken.Weitere Informationen: http://parashift.com/c++-faq-lite/ctors.html#faq-10.13

Seit ich dieses Problem und seine Lösung gefunden habe, habe ich gelernt, dass es wichtig ist zu verstehen, wie Statik zwischen Ihren statisch und dynamisch verbundenen Bibliotheken geteilt oder nicht geteilt wird. Unter Windows erfordert dies den expliziten Export der Symbole für die geteilten Statiken (einschließlich Dingen wie Singles, auf die über verschiedene Bibliotheken hinweg zugegriffen werden soll). Das Verhalten unterscheidet sich subtil zwischen jeder der Hauptplattformen.

+0

Akzeptiere dies auch als Antwort :) – sarnold

1

Mit dem gleichen Problem mit SWIG für Python mit einer cpp-Bibliothek (Clipper), fand ich, dass mit LD_PRELOAD, wie Sie vorgeschlagen, funktioniert auch für mich. Als eine andere Problemumgehung, die LD_PRELOAD nicht benötigt, habe ich festgestellt, dass ich auch die libstdC++ in die .so Bibliotheksdatei meines Moduls, z.

Ich kann es dann in Python ohne weitere Optionen importieren.

1

Ich realisiere, dass @lefticus die Antwort in Bezug auf was ich vermutete auf undefinierte statische Init-Reihenfolge akzeptiert; Allerdings hatte ich ein sehr ähnliches Problem, diesmal mit .

Ich versuchte mein Bestes, irgendwelche statischen Initialisierungsprobleme zu finden und konnte nicht - bis zu dem Punkt, dass ich einen großen Teil unserer Codebasis refaktorierte; und als das nicht funktionierte, endete das Entfernen von Ausnahmen.

Es schlichen sich aber noch mehr ein und wir begannen diese Segfaults wieder zu bekommen.

Nach einigen weiteren Untersuchungen stieß ich auf this link, die über benutzerdefinierte Zuordner spricht.

Wir verwenden tatsächlich tcmalloc selbst; und nachdem ich es aus unserer Bibliothek entfernt habe, die nach exportiert wird, hatten wir keine Probleme mehr!

Also nur ein FYI an jeden, der über diesen Thread stolpert - wenn @ lefticus die Antwort nicht funktioniert, überprüfen Sie, ob Sie einen anderen Zuordner als den verwenden, der python verwendet.

2

Ich habe kürzlich auch in dieses Problem geraten. Mein Prozess erstellt ein gemeinsames Objektmodul, das als Python-C++ - Erweiterung verwendet wird. Ein aktuelles Betriebssystem-Upgrade von RHEL 6.4 auf 6.5 hat das Problem aufgedeckt.

Nach den hier aufgeführten Tipps habe ich nur -lstdC++ zu meinen Link-Switches hinzugefügt, und das hat das Problem gelöst.