Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / October 2004

Tip: Looking for answers? Try searching our database.

Problem with locales in unloaded DLLs

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Hendrik Schober - 26 Oct 2004 17:23 GMT
[x-posted to microsoft.public.dotnet.languages.vc
and microsoft.public.vc.stl]

Hi,

we just ran into a bug that seems to be a show-
stopper for us.
We are making a plugin (DLL) for some application.
It is loaded from the app (presumably) using
'LoadLibrary()'. Then code in the DLL is executed.
Sometimes, this implies calls to 'std::issspace()'
which in turn will call 'locale::facet::_Register()'
to register a locale with the C++ runtime. Later
on, the DLL will be unloaded. However, the run-
time only treis to un-register the facet when the
/process/ terminates. At this time the DLL is long
gone and the app thus crashes at shutdown.

A search across the KB (using the term "register
locale crash") didn't come up with something.
Google did find a reference to what appears to be
this bug. (Search for the string "DINKUMWARE BUG"
on http://cvs.sourceforge.net/viewcvs.py/filezilla/FileZilla%20Server/source/misc/S
tdString.h?rev=1.4
)

Is there any fix for this? We use a few 3rd-party
libs that call locale-dependend functions which
will trigger this bug. It would be a huge problem
if we had to go through all this code and try to
understand it in order to fix the problem.

TIA,

Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Doug Harrison [MVP] - 26 Oct 2004 19:38 GMT
>[x-posted to microsoft.public.dotnet.languages.vc
>and microsoft.public.vc.stl]
[quoted text clipped - 25 lines]
>if we had to go through all this code and try to
>understand it in order to fix the problem.

Can't you solve this problem by statically linking to the C and C++
runtimes? I think that's a very appropriate thing to do for plug-in DLLs, or
in general, DLLs that can be loaded into unknown environments, such as
Windows global hook DLLs, DLLs that implement coclasses, etc.

Signature

Doug Harrison
Microsoft MVP - Visual C++

Hendrik Schober - 26 Oct 2004 21:35 GMT
> [...]
>
> Can't you solve this problem by statically linking to the C and C++
> runtimes? I think that's a very appropriate thing to do for plug-in DLLs, or
> in general, DLLs that can be loaded into unknown environments, such as
> Windows global hook DLLs, DLLs that implement coclasses, etc.

 I wouldn't have thought this could fix the
 problem. I can try this tomorrow when I'm
 back at work.
 But isn't this the same then? The DLL is
 loaded, the RTL gets initialized, the code
 runs, and at the end, the DLL is unloaded,
 for which the RTL needs to do the cleanup.
 If the RTL stores some pointer somewhere
 to an object that's to be deleted, and it
 will try to delete it at process' end, then
 the DLL (and the object) will be gone.
 Or am I missing something?

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Igor Tandetnik - 26 Oct 2004 21:59 GMT
>> [...]
>>
[quoted text clipped - 11 lines]
>  runs, and at the end, the DLL is unloaded,
>  for which the RTL needs to do the cleanup.

When linked statically, the DLL has its own copy of CRT, which performs
its own initialization and clean-up independently of the EXE. This
private copy initializes when the DLL loads, and cleans up when the DLL
unloads.
Signature

With best wishes,
   Igor Tandetnik

"On two occasions, I have been asked [by members of Parliament], 'Pray,
Mr. Babbage, if you put into the machine wrong figures, will the right
answers come out?' I am not able to rightly apprehend the kind of
confusion of ideas that could provoke such a question." -- Charles
Babbage

Hendrik Schober - 27 Oct 2004 10:03 GMT
> [...]
>
> When linked statically, the DLL has its own copy of CRT, which performs
> its own initialization and clean-up independently of the EXE. This
> private copy initializes when the DLL loads, and cleans up when the DLL
> unloads.

 I see. Thanks for the clarification.
 Meanwhile I have checked with the company
 that makes the application we're doing
 the plugin for. They agreed that this bug
 was introduced by dynamically linking to
 the RTL.
 However, they also say that dynamically
 linking to the RTL speeds up the startup
 considerably. (There are many plugins.)
 So I am asked to keep the dynamic linking
 and fix the problem anyway. <sigh>

 Isn't there a fix for this??? This bug
 effectively prevents DLLs from dynamically
 linking to the RTL! This surely must have
 affected /many/ users.

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Vladimir Nesterovsky - 27 Oct 2004 12:27 GMT
One way to fix this is not to unload DLL. Just add one uncompensated
LoadLibrary call into your code.
This isn't so terrible as it seems.
Signature

Vladimir Nesterovsky
e-mail: vladimir@nesterovsky-bros.com
home: www.nesterovsky-bros.com

> > When linked statically, the DLL has its own copy of CRT, which performs
> > its own initialization and clean-up independently of the EXE. This
[quoted text clipped - 17 lines]
>   linking to the RTL! This surely must have
>   affected /many/ users.
Hendrik Schober - 27 Oct 2004 13:12 GMT
> One way to fix this is not to unload DLL. Just add one uncompensated
> LoadLibrary call into your code.
> This isn't so terrible as it seems.

 The problem is, this isn't our code.
 We don't even get to see the source.
 All we have is a plugin API and a
 binary.

> [...]

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Vladimir Nesterovsky - 27 Oct 2004 13:56 GMT
> > One way to fix this is not to unload DLL. Just add one uncompensated
> > LoadLibrary call into your code.
[quoted text clipped - 4 lines]
>   All we have is a plugin API and a
>   binary.

You can call LoadLibrary from within your code. But be sure not to invoke
LoadLibrary from the DllMain.

// YourClass is never instantiated in the DllMain.
class YourClass
{
private:
   static bool Initialize()
   {
       return LoadLibrary("your library") != 0;
   }
public:
   YourClass()
   {
       static bool initialized = Initialize();

       ...
   }
};

Signature

Vladimir Nesterovsky
e-mail: vladimir@nesterovsky-bros.com
home: www.nesterovsky-bros.com

Doug Harrison [MVP] - 27 Oct 2004 17:43 GMT
>You can call LoadLibrary from within your code. But be sure not to invoke
>LoadLibrary from the DllMain.
[quoted text clipped - 15 lines]
>    }
>};

And remember that DLL globals are initialized by DllMain, so you mustn't
have a DLL global YourClass, or a DLL global which uses YourClass. Also,
it's worth mentioning that local statics in DLLs typically aren't destroyed
in accordance with the standard's LIFO policy; much more on that here:

http://groups.google.com/groups?selm=r08j009jlkjck5gdedti38h66p0gfpbcf3%404ax.com

To summarize the warning in that message, if you have a DLL local static
that is only ever initialized by the EXE, the destructor for that object
will be run in DllMain context and must obey the DllMain restrictions.

Signature

Doug Harrison
Microsoft MVP - Visual C++

Doug Harrison [MVP] - 27 Oct 2004 17:43 GMT
>  But isn't this the same then? The DLL is
>  loaded, the RTL gets initialized, the code
[quoted text clipped - 5 lines]
>  the DLL (and the object) will be gone.
>  Or am I missing something?

That's an interesting question. Let's assume that when it's shutting down,
the RTL will execute a dtor residing in a DLL that was never unloaded but
has already been uninitialized. Further, we'll assume both EXE and DLL link
to the same CRT, so there's only one heap. IOW, we have an app that
implicitly links to DLLs that become tightly integrated into it.

I don't think there are any data issues distinct from the case of an
application that uses static linking throughout. So, is the DLL dtor code
still mapped into the process? I've looked into this before but never found
a concrete answer. Empirically speaking, I'd bet yes, but it does seem like
it would be in a weird state of limbo, executing after the DLL received its
DLL_PROCESS_DETACH notification.

Signature

Doug Harrison
Microsoft MVP - Visual C++

Hendrik Schober - 28 Oct 2004 09:57 GMT
> >  But isn't this the same then? The DLL is
> >  loaded, the RTL gets initialized, the code
[quoted text clipped - 18 lines]
> it would be in a weird state of limbo, executing after the DLL received its
> DLL_PROCESS_DETACH notification.

 IIUC, the issue is a stored vptr referencing
 a vtable in the already unloaded DLL.
 As I had to find out last night <yawn>, the
 problem isn't easily reproducable. I am still
 not sure about what is necessary.

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.