From: Marcus L. <ma...@ya...> - 2008-11-27 14:45:06
|
Gerrit Voss wrote: > Hi, > > sorry for the delay, end of term and the 64bit boost stuff kept me busy. > > On Thu, 2008-11-27 at 14:15 +0100, Marcus Lindblom wrote: > >> Stepping in the debugger clearly says that the _defaultMaterial ptr gets >> destructed (by the static initializer's atexit) before the >> subrefdefaultmaterial() function is called by osgExit(). >> >> Which goes against the standard and how we thought it would behave! > > not quite, the standard at that point is sprinkled with 'implementation > dependent'. Also the only guarantee that is in there is that POD types > are set to 0 at the very start and constant expressions are evaluated > before the rest. Anything else, especially when to do function calls for > initialization is dependent on the compiler. And it is explicitly > allowed to do that after main started. > > e.g : > > An implementation is permitted to perform the initialization of an > object of namespace scope with static storage duration as a static > initialization even if such initialization is not required to be done > statically > > It is implementation-defined whether or not the dynamic initialization > (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before > the first statement of main. If the initialization is deferred to some > point in time after the first statement of main, it shall occur before > the first use of any function or object defined in the same translation > unit as the object to be initialized Right. But does that say that the destruction order of dynamically initalized objects may be different from the initialization order (interleaved with atexit calls)? All these objects have static storage duration, if I'm not mistaken? So, going back to 3.6.3 §3, atexit() should stil be ordered viz. intialization of static storage objects, which does not happen here. Anyway, we just need to decide what to do with this behaviour, regardless of it's conformance to the standard. >> After stepping through things and looking carefully at the call stack, >> it seems as if atexit() calls are bunched per dll, which explains the >> current behaviour: >> >> OSGSystem.dll (with has it's statically intialized defaultmaterial) is >> deallocated before OSGBase.dll (which gets the atexit(osgexit)). >> >> Doing like that seems way too crazy though, unless there is something >> wrong with the linking to runtime libs, so that each dll gets it's own >> atexit-list. > > Well the MS dll concept is quite crazy (import/export or jump tables > anybody (especially funny if you keep looping inside those) ;-)), so I > would not be to surprised. Yeah, it does seem as if each dll has it's atexit() list. Oh well. > What makes me curious is that there are quite some virtual function > calls from osgExit to OSGSystem so if OSGSystem goes out of life before > the osgExit handler is called interesting things should happen and this > one pointer will be the smallest of problems ;-). Except if I really > took enough care and guessed that this could actually happen, which I > don't really believe I did. I think the code is not unloaded until each dll has got it's process-detached message (and thus each list of atexit-functions have run). > I'll give it a try tomorrow. > >> How to fix that? Simply don't use static MTRecPtr's? That ought to be >> safe, no, since the subrefmaterial()-functions are always called by >> osgexit()? > > I still tend to enforce explicit osgExit calls. I'm with you on that. Especially as it seems to be required to make things work on win32. Can we agree that explicit osgexit() is required and remove the atexit() call in osgInit() then? I just feel we need to be very clear and explicit about this to everyone who uses OpenSG. Cheers /Marcus |