Hi all,

Gerrit Voss wrote:
> 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:
>> (I think I've got it! :)
>>
>> Carsten Neumann wrote:
>>
>>>> (Also, are the MTRefPtr's nulled in their dtor? I don't think so. 
>>>> Perhaps that's a good idea to avoid accessing stale objects?)
>>> yes, I've tried that and it prevents the crash, because the assignment 
>>> in subRefDefaultMaterial simply does nothing. However, the assignment 
>>> itself makes use of the _defaultMaterial pointer object, which is (or at 
>>> least seems to be) dead at that point. So setting the MTRefPtr::_pObj to 
>>> NULL solves the crash (at least for me), but still operates on an 
>>> destroyed object, which is an even more subtle issue.
>> I agree.
>>
>>>> Hm, I'll have to run the debugger a bit myself I think. :)
>>> This is an interesting problem, if you find out anything please let me 
>>> know, I appreciate your help in getting to the bottom of this.
>> 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

yes, that is what sometimes makes problems with the file type 
registration, since OSGFileIO.dll is normally only used indirectly 
through SceneFileHandler.

>> 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.

yes, talking with a colleague (thanks Aashish!) yesterday and some 
googeling we came to the same result, DLLs have their own atexit handler 
stack. And since osgInit is in the OSGBase.dll the osgExitWrapper ends 
up on that atexit stack.
 From what we read, it is also the case that atexit handlers registered 
from the application (i.e. not a DLL) end up on a stack that runs before 
DLL unloading begins, so if we can get onto that stack everything should 
be fine.
I wanted to try to inline that part of osgInit (basically split it into 
the bulk of its body and the atexit registration and make sure the 
latter is inlined into main). The other thing I wanted to look into was 
if there is some windows specific way to register an atexit handler on 
the application atexit stack from inside a DLL - don't have high hopes 
on that though.

> 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.
> 
> 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'll give it a try tomorrow.

hm, slightly scary ;) Anyways if we can get the osgExitWrapper on the 
app atexit stack everything is good :)

>> 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.  

yes, if the inline trick does not work, that was the only alternative I 
could think of.

        regards,
                Carsten


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to