2016-04-09 5 views
3

Nach einigen Recherchen schließe ich schließlich SO meine Frage zu stellen: Was passiert mit Speicher dynamisch zugewiesen von einer gemeinsamen Bibliothek (mit malloc() oder new) nach dem Schließen der Bibliothek mit dlclose() ? Das Verhalten, das ich beobachtete, ist, dass jeder Zugriff auf solchen Speicher (Dereferenzierung, unter Verwendung von delete Operator damit etc.) zu einem Segmentierungsfehler führt. Ist es irgendwo definiert?Zugriff auf Speicher freigegeben durch shared library nach dlclose()

Nun scheint es wie eine dumme Frage, zu fragen, wenn ich dlclose() wissen anruft, bevor ich mit der Erinnerung wurde die Quelle des Fehlers beendet wurde - unter Verwendung delete Operator auf einem new -created Objekt aus einer gemeinsam genutzten Bibliothek erhalten ausgelöst - Ich habe in den letzten paar Tagen dagegen gekämpft, aber ich würde gerne wissen warum, anstatt nur zu raten, falls ich in Zukunft auf eine ähnliche Situation stoße.

+0

Möglicherweise verwandte Fragen: https://stackoverflow.com/questions/31375177/why-might-mallocd-memory-from-a-shared-library-be-inaccessible-to-the-applicati https: // stackoverflow. com/questions/4732018/Was passiert mit der globalen Variablen-in-shared-library-wann-dlclose-ist-aufgerufen-https://stackoverflow.com/questions/36420174/linux-cc-allocate -deallocate-memory-in-dynamic-library – Mael

Antwort

4

was passiert mit dem Speicher, der von einer gemeinsam genutzten Bibliothek zugewiesen wird, nachdem die Bibliothek mit dlclose() geschlossen wurde.

Es hängt auf, was Sie mit "zugewiesen".

Es gibt mindestens drei Fälle zu betrachten:

  1. Speicher zugeordnet ist malloc oder new verwenden. dlclose wird keine Wirkung haben.
  2. Ein globaler innerhalb der Bibliothek. dlclose()kannmunmap() der Speicher (oder nicht; abhängig davon, ob andere Symbole aus der Bibliothek verwendet wurden). Wenn munmap passiert, wird der Speicher vollständig unzugänglich sein.
  3. Bibliothek erstellt ein globales Objekt (z. B. global std::string). Das Objekt ordnet den internen Speicher für sich selbst unter Verwendung von ::new zu (wie string würde). Wenn die Bibliothek dlclose d ist, kann das Objekt zerstört werden. Wenn es zerstört wird, wird es ::delete dieser Speicher. Der Speicher wird wahrscheinlich immer noch zugänglich sein, aber der Zugriff darauf ruft ein undefiniertes Verhalten auf (genau wie jeder andere Zugang zu freiem Speicher).

Update:

Für Fall # 1, die new d Speicher noch zugänglich sein. Aber alle verschachtelten Zeiger innerhalb dieser new d Objekt möglicherweise nicht. Wenn das Objekt in C++ über virtuelle Funktionen verfügt, wird der Zeiger auf den virtuellen Tabellenzugriff möglicherweise nicht mehr verfügbar (er zeigt auf schreibgeschützte Daten innerhalb der jetzt entladenen foo.so), und dieser Fall entspricht # 2.

Haben Sie irgendwelche Hinweise, denen ich folgen sollte, um herauszufinden, was schief gelaufen ist?

Ja: die übliche Debug-Technik verwenden: das Programm unter GDB laufen, herauszufinden, wo genau stürzt. Wenn Sie den Absturz immer noch nicht verstehen, bearbeiten Sie Ihre Frage mit Code, der zeigt, was das Programm macht, und GDB-Ausgabe dafür.

+0

Danke. Ich habe die Frage bearbeitet, um zu verdeutlichen, dass ich auf den vom Operator 'new' zugewiesenen Speicher zugreife. Aber wenn Sie 'dclclose()' sagen -die Bibliothek würde keinen Effekt auf diesen Speicher haben, muss der Fehler woanders sein - für mich sah es so aus, als wäre das genau der Fall, und der Zugriff auf das Objekt löste einen segfault aus. Hast du irgendwelche Hinweise, denen ich folgen sollte, um herauszufinden, was schief gelaufen ist? – Mael

+0

@Mael Ich habe die Antwort aktualisiert. –

+0

@EmployedRussion Dies ist, was ich gesucht habe: * virtueller Tabellenzeiger kann unzugänglich werden *. Die von '.so' zugewiesenen Objekte hatten virtuelle Destruktoren - was erklärt, warum der segfault durch den Aufruf des 'delete'-Operators ausgelöst wurde. Danke für das Teilen von Wissen. Ich habe deine Antwort als akzeptiert markiert. – Mael

0

Der Speicher wird an das Betriebssystem zurückgegeben. Alle übrig gebliebenen Referenzen sind ungültig und gehören nicht mehr zu Ihrem Prozess, weshalb der Versuch, etwas mit ihnen zu tun, zu einem Segfault führt.

+0

Dies ist eine * komplett * falsche Antwort. –

Verwandte Themen