From: stephan b. <st...@s1...> - 2004-12-23 23:17:42
|
On Thursday 23 December 2004 23:55, Christian Prochnow wrote: > Am Donnerstag 23 Dezember 2004 22:08 schrieb stephan beal: > > Yo! > > > > i'm adding SharedLib.ltdl.cpp (uses GNU libltdl, portable libdl > > replacement) and i noticed this code in SharedLib.dl.cpp: > > which other DLL APIs does libltdl support ? i thought we catched > every DLL API with the existing dl, shl, dyld and win32 > implementations !? It's not a question of whether libltdl supports another lib loader. Suppose i open Foo.so. Foo.so can run arbitrary code and IT can use, e.g., dlopen(). If SharedLib dlcloses() in the dtor then we close Foo.so, but the libs dlopen()ed by Foo.so might not be shut down. Those dlls might leave artefacts in memory which we still rely on, like object factories. > While this is a problem with the CL architecture .. in general it is > not. In fact, when DLLs are unloaded which register themselves upon > loading, they should also deregister themselves from the CL. That assumes that the DLL knows how to do so. AFAIK this is loader-dependent. e.g., libdl looks for the symbol _fine() (i think that's the name) and calls if it exists. We can't ask loadable classes to know what dlopen implementation they're using. > Anyway for objects created within the loaded DLL you're right, it > would be unpractial to keep track of ownership and to destroy all > instances created form within the DLL we're unloading. Do you think > it is possible to "transfer" ownership of objects allocated in DLLs > to the app ? "Jein". This is difficult to answer without giving some details about the CL model. Here's how a CL lookup works: a) Do we have a factory for KEY? If so, run that factory. b) Can we find a DLL for KEY.so? If so, open it. The static-init phase of the DLL triggers factory registrations living in that DLL. They simply call Factory<InterfaceT>::registerxxxx("myclassname",myfactory). c) Repeat (a). If we have no factory, return 0. The DLL did not have what we wanted, so we could ARGUABLY dlclose() it, but the fact is that we cannot know what other DLLs it has opened, and this HAS causes crashes for me in real use cases. What this means is that the DLLs register themselves with the factory, without the factory actually having to know. Opening ANY DLL can trigger an arbitrary number of factory registrations. Consider doing this in your app's init code: P::System::openSharedLib( "/path/to/my_common_classes.so" ); That might have just registered 27 classes across 5 different factories. And it might not have done anything at all! As far as SharedLib ownership goes: see the impl of openSharedLibrary() SharedLib.generic.cpp. i believe that one is relatively sane, and it works using the platform-defined SharedLib. > This is not a problem. In fact SharedLib owns the pointers one can > retrieve with the operator[]. If this is documented everything is > fine. i'm not thinking about symbol-level access. i'm thinking about the factories which were registered via static-init. If dlclose() is called, those factories point to nirgendwo, or maybe even point to some other valid memory after the next dlopen! Eeeek! > DLLs have a "init" and "shutdown" function. Maybe the Factory > pointers can be removed by the shutdown function when unloading the > DLL. That's lib-loader-dependent. That means the static init code must know what loader it's using. The static init code normally looks like the following global-scope code, and is 100% symbol/load-independent: void my_init() { ... register my factories ... } int my_init_placeholder = (my_init(),0); That is how we achieve 100% symbol-ignorance in the CL registration layer. -- ----- st...@s1... http://s11n.net "...pleasure is a grace and is not obedient to the commands of the will." -- Alan W. Watts |