Frage

Plugin1.cpp:

#include <iostream>

static class TestStatic {
public:
  TestStatic() {
     std::cout << "TestStatic create" << std::endl;
  }
  ~TestStatic() {
     std::cout << "TestStatic destroy" << std::endl;
  }
} test_static;

Host.cpp

#include <dlfcn.h>
#include <iostream>
int main(int argc,char *argv[]) {
   void* handle = dlopen("./plugin1.so",RTLD_NOW | RTLD_LOCAL );
   dlclose(handle);
   return 0;
}

bauen und rennen:

>g++ -c plugin1.cpp -o plugin1.o -fPIC
>g++ -shared plugin.o -o plugin1.so
>g++ host.cpp -o host -ldl
>./host
>TestStatic create
>Segmentation fault

Warum teststatic :: ~ teststatic auf 'exit ()' ', aber nicht bei' dlclose () '?

War es hilfreich?

Lösung

Der C ++ - Standard erfordert, dass Destruktoren globale Objekte auffordert, wenn ein Programm in der entgegengesetzten Reihenfolge der Konstruktion verlässt. Die meisten Implementierungen haben dies behandelt, indem die C -Bibliothek ATEXIT -Routine aufgerufen wird, um die Zerstörer zu registrieren. Dies ist problematisch, da der C -Standard von 1999 nur die implementierende implementierende 32 registrierte Funktionen unterstützt, obwohl die meisten Implementierungen viel mehr unterstützen. Noch wichtiger ist, dass es in den meisten Implementierungen überhaupt nicht mit der Fähigkeit handelt, DSOs aus einem laufenden Programmbild zu entfernen, indem DLCLOSE vor der Programmabgabe aufgerufen wird.

Dieses Problem wird in späteren Versionen von GCC, einschließlich C/C ++ - Standardbibliothek und Linker, behandelt. Grundsätzlich sollten C ++ - Zerstörer mit Verwendung registriert werden __cxa_atexit Funktion anstelle von atexit (3).

Für die vollständigen technischen Details zu __cxa_atexit, sehen Itanium C ++ ABI -Spezifikation.


Aus Ihrer Frage ist nicht klar, welche Version der GCC-, Linker- und Standard -C -Bibliothek Sie verwenden. Außerdem erfüllt sich der Code, den Sie bereitgestellt haben Posix Standard, da es keine gibt RTDL_NOW oder RTDL_LOCAL Makros definiert. Sie sind RTLD_NOW und RTLD_LOCAL (sehen DLOPEN).

Wenn Ihre C -Standardbibliothek nicht unterstützt __cxa_atexit, Möglicherweise müssen Sie es deaktivieren, indem Sie angeben -fno-use-cxa-atexit GCC -Flagge:

-Fuse-cxa-atexit

Registrieren Sie Zerstörer für Objekte mit statischer Speicherdauer mit der Funktion __CXA_ ATEXIT und nicht mit der Atexit -Funktion. Diese Option ist für die vollständig standardmäßige Behandlung statischer Zerstörer erforderlich, funktioniert jedoch nur, wenn Ihre C-Bibliothek __cxa_atexit unterstützt.

Dies könnte jedoch zu einem Problem führen, bei dem Zerstörer in unterschiedlicher Reihenfolge oder gar nicht berufen werden. Also die beste Lösung bei kaputten Fall __cxa_atexit Unterstützung oder überhaupt nicht unterstützt, besteht darin, statische Objekte mit Zerstörern in Ihren gemeinsamen Bibliotheken zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top