Boost logo

Boost :

Subject: Re: [boost] [Locale] Static locale initialisation
From: Alexander Lamaison (awl03_at_[hidden])
Date: 2010-04-11 08:09:29


On Sat, 10 Apr 2010 13:07:47 -0700 (PDT), Artyom wrote:

>> You were right about that cause of that crash: i had mixed
>> Release and
>> Debug DLLs (that is a problem in its own right as typically
>> you aren't in
>> control of other DLLs)
>
> So I do not understand fixing correct runtime solved your problem
> or not?

No, it just stopped the double-delete

>> Basically what happens is that the DLL sets the global
>> locale when it is
>> loaded. Great. We work away doing stuff and
>> everything is fine ...
>>
>> Then at some point the DLL is unloaded. But the
>> global locale is still
>> pointing at an object whose definition was provided by the
>> non-unloaded
>> DLL. Disaster! The next time anything tries to
>> use a locale (like a
>> simple stream op) we crash with an access violation.
>>
>> The problem here is setting a locale 'owned' by the
>> DLL. Is there a way
>> round this?
>
> This code reproduces the issue of crash when you set global locale
> and then you do not unload it, at least I see that you
> do not call std::locale::global(std::locale::classic()) . Am I right?

Yes, I wasn't doing that.

> If so.. this is your problem and not Boost.Locale one.
>
> It can be recreated even on Linux with shared objects,
> if you create global locale in dynamic library and unload the library
> you will crash when you would try to create an locale instance - clearly.

Can you add this to the documentation becuase its not at all obvious -
there is no mention of cleanup.

> Does it crashes when you call on library unload:
>
> std::locale::global(std::locale::classic());

Yes, this fixes the crash. In fact, what I'm doing now is saving the old
locale and restoring that when unloading so that if tow modules use
boost.locale and one unloads, its doesn't destroy boost.locale for the
other.

> In any case:
>
> - It seems to be rather standard library issue then Boost.Locale one
> - Any DLL that would create its own facets and set global locale would
> have this issue.

You're probably right but it needs to be documented explicitly. I've never
come across a situation before where you have to do cleanup before
unloading a DLL.

Now that *that* part (not crashing) is fixed, I'm running into another
problem. I can see the .mo file being loaded; excellent! But when I try
to translate a string, the translation mechanism fails to find it! This
only happens when i set the locale statically. If I set it just before
using translate() it works fine.

Here is the repro code: http://www.doc.ic.ac.uk/~awl03/locale_test2.zip

To see the different situations, change which commentted line declaring
LocaleSetup. The problem seems to be that std::has_facet looks for a Facet
with an id of 46 (0x2e). But when it gets to this line:

    const facet *_Facptr = _Id < _Ptr->_Facetcount
                 ? _Ptr->_Facetvec[_Id] : 0; // null if id off end

_Facetcount is 46 so it decides it's off the end. I notice that in the
working version _Facet::id is 44 (0x2c).

Any idea what's happening here?

Many thanks.

Alex


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk