Strange DLL problem?

  • Thread starter Martin Christiansen
  • Start date
M

Martin Christiansen

Hi all.

I have a strange problem:



Hardware:

Psion industry-PDA running Windows Mobile 6 + .NET Compact Framework (2.0 I
think).



Problem:

On that unit I run a small shell program named AppLauncher (home made,
..net), that I can use to start other programs.

Now I choose to let this shell program start another .NET program called
'RDC':

RDC.EXE is located in its own folder. RDC.EXE starts and runs as planned,
and RDC makes use of a few other DLL's. Among these DLLs is PtxSdkCommon.dll
which is a DLL interfacing to the handheld's hardware. PtxSdkCommon.dll may
be a 'normal' (unmanaged) dll.

After having finished working with the RDC program I close it, and I find
myself back in the shell program. Everything looks fine, except for the
fact, that the PtxSdkCommon.dll is still reported to be in use - thus it
cannot be deleted from the file system!

This is very strange, because when I check the list of running programs, the
RDC program is not (and should not be) present in the list - only the shell
program is listed.

Despite that the shell program has absolutely no knowledge of the
PtxSdkCommon.dll, that DLL reamains locked until I kill the shell program.
Only then the PtxSdkCommon.dll can be deleted. It is only that particular
DLL, that is locked - all other DLLs that the RDC program uses can be
deleted without any problems.

What is happening here???

It should be mentioned, that if I just start the shell program *without*
letting it start the RDC program, then there is no problem in deleting the
PtxSdkCommon.dll.




Technical background information:


The shell program starts the RDC program this way:


1) The shell program creates a new AppDomain for the RDC program to run in:

executingDomain = AppDomain.CreateDomain(...);

2) The shell program starts a new thread that in turn starts the RDC program
this way:

executingDomain.ExecuteAssembly( <path to RDC.EXE> )

This call does not return until RDC.EXE is closed by the user.

3) When RDC.EXE is closed the call above returns, and the thread tears down
the AppDomain:

AppDomain.Unload( executingDomain )


It's being checked that AppDomain.Unload(...) does not cause any exceptions,
so the unload of the AppDomain is assumed to have completed successfully. It
should be said, though, that it's not the same thread that takes care of
both creation and unloading the AppDomain. Does that matter?

According to the documentation a succesfull unload should guarantee that all
threads have been killed and all assemblies freed, right? How can the
PtxSdkCommon.dll then remain locked??? How can I overcome the problem? (I
need to be able to upgrade/replace all the files in the RDC folder,
including the PtxSdkCommon.dll, without closing down the shell program or
rebooting the device).

Hope that someone can explain.


-Martin.
 
P

Paul G. Tobey [eMVP]

You closed RDC how? Clicking on the X button does not close the
application, so it wouldn't be any surprise if the DLL was still in use (the
application that uses it is still running). Look up "smart minimize" in the
archives...

Paul T.
 
M

Martin Christiansen

"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com said:
You closed RDC how? Clicking on the X button does not close the
application, so it wouldn't be any surprise if the DLL was still in use
(the application that uses it is still running). Look up "smart minimize"
in the archives...

Paul T.
I will do that.

The RDC program is a normal Windows Forms application (for Compact
Framework) created in VS2005. I've seen several other PDA applications that
did not really close when clicking the X button, but then the program was
still listed in the Settings->Memroy->Running list (and the RDC program is
not). Furthermore, it appearently helps killing the shell program, even
though it's the RDC program that is using the DLL. How does that conform to
your idea about the RDC appliction still running???

I'll revert here once I have read about "smart minimize". Thank you so far.

-Martin.
 
P

Paul G. Tobey [eMVP]

The way in which the program is written is what determines whether it will
exit or not. If the X button is there on a Windows Mobile managed code
application, it's not going to exit. You can change the application
properties to change that X to an OK and clicking that *will* exit the
program, but that's pretty obvious in the UI. If the window is hidden, it
won't appear in the running programs list, so that, while it's a useful
indication, is not foolproof. If the shell program is calling
CreateProcess(), effectively, to launch RDC, the shell program is not
responsible for the loading of that other application's DLLs. It could be
that your shell program is waiting for RDC to exit and, therefore, is fairly
locked-up until you really exit RDC or kill the shell program, but only
you'd really know what's going on with that.

Paul T.

Martin Christiansen said:
"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com said:
You closed RDC how? Clicking on the X button does not close the
application, so it wouldn't be any surprise if the DLL was still in use
(the application that uses it is still running). Look up "smart
minimize" in the archives...

Paul T.
I will do that.

The RDC program is a normal Windows Forms application (for Compact
Framework) created in VS2005. I've seen several other PDA applications
that did not really close when clicking the X button, but then the program
was still listed in the Settings->Memroy->Running list (and the RDC
program is not). Furthermore, it appearently helps killing the shell
program, even though it's the RDC program that is using the DLL. How does
that conform to your idea about the RDC appliction still running???

I'll revert here once I have read about "smart minimize". Thank you so
far.

-Martin.
 
M

Martin Christiansen

"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com> skrev i en meddelelse news:[email protected]...
The way in which the program is written is what determines whether it will
exit or not. If the X button is there on a Windows Mobile managed code
application, it's not going to exit. You can change the application
properties to change that X to an OK and clicking that *will* exit the
program, but that's pretty obvious in the UI. If the window is hidden, it
won't appear in the running programs list, so that, while it's a useful
indication, is not foolproof. If the shell program is calling
CreateProcess(), effectively, to launch RDC, the shell program is not
responsible for the loading of that other application's DLLs. It could be
that your shell program is waiting for RDC to exit and, therefore, is
fairly locked-up until you really exit RDC or kill the shell program, but
only you'd really know what's going on with that.

Paul T.

I'm not at work right now, so I'm not 100% sure if it's an X or an OK. I am,
however, pretty sure that the RDC application has terminated all right,
because the ExecuteAssembly(...) call that started the RDC application does
not terminate until I close the RDC application. And when it eventually
does, then it furthermore succeeds in unloading the AppDomain.

Maybe all this talk about AppDomains and managed applications really doesn't
matter when it comes to native DLLs? Could it be that the RDC application
reallly has terminated, but the native DLL remains because it has still some
living threads, it has created? And if so, what chances do I then have of
getting rid of the garbage?

- Martin.
 
P

Paul G. Tobey [eMVP]

The application won't terminate until all of its threads have exited. If
you are creating threads, you need to take care, before exiting, to close
them all cleanly.

Paul T.

Martin Christiansen said:
"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com> skrev i en meddelelse news:[email protected]...
The way in which the program is written is what determines whether it
will exit or not. If the X button is there on a Windows Mobile managed
code application, it's not going to exit. You can change the application
properties to change that X to an OK and clicking that *will* exit the
program, but that's pretty obvious in the UI. If the window is hidden,
it won't appear in the running programs list, so that, while it's a
useful indication, is not foolproof. If the shell program is calling
CreateProcess(), effectively, to launch RDC, the shell program is not
responsible for the loading of that other application's DLLs. It could
be that your shell program is waiting for RDC to exit and, therefore, is
fairly locked-up until you really exit RDC or kill the shell program, but
only you'd really know what's going on with that.

Paul T.

I'm not at work right now, so I'm not 100% sure if it's an X or an OK. I
am, however, pretty sure that the RDC application has terminated all
right, because the ExecuteAssembly(...) call that started the RDC
application does not terminate until I close the RDC application. And when
it eventually does, then it furthermore succeeds in unloading the
AppDomain.

Maybe all this talk about AppDomains and managed applications really
doesn't matter when it comes to native DLLs? Could it be that the RDC
application reallly has terminated, but the native DLL remains because it
has still some living threads, it has created? And if so, what chances do
I then have of getting rid of the garbage?

- Martin.
 
M

Martin Christiansen

"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com> skrev i en meddelelse news:%[email protected]...
The application won't terminate until all of its threads have exited. If
you are creating threads, you need to take care, before exiting, to close
them all cleanly.

Paul T.

Hi again.

I have now solved problem, and the solution was pretty simple:

I have now changed the shell program not to start the RDC.EXE by creating a
new AppDomain (and running RDC.EXE in it). Instead the shell program now
uses Process.Start(...) to launch the RDC.EXE. When RDC.EXE eventually
terminates, the famous DLL does not hang any more and it can be deleted
right away.

My own explanation for this different behaviour is this:

A Win32 process is the owner of a native DLL, not an AppDomain. In the new
scenario two different processes run each one AppDomain, where before one
single process ran both AppDomains. Since the owning process of the native
DLL is now the new process (that dies when RDC.EXE terminates), the DLL is
now freed as planned.

Don't you think this explanation sounds resonable?


Anyway, thank you very much for your participation in my problem - it's
great to have place to ask for help, and hopefully we all got a little bit
wiser.

-Martin.
 
P

Paul G. Tobey [eMVP]

I'm afraid that I know about as much about AppDomains as I do about
open-heart surgery. One would think that the DLL would be released at some
point, no matter what, but maybe there's a bug there that prevents the
collection of whatever corresponds to a native DLL reference. I'm glad you
got it fixed...

Paul T.

Martin Christiansen said:
"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com> skrev i en meddelelse news:%[email protected]...
The application won't terminate until all of its threads have exited. If
you are creating threads, you need to take care, before exiting, to close
them all cleanly.

Paul T.

Hi again.

I have now solved problem, and the solution was pretty simple:

I have now changed the shell program not to start the RDC.EXE by creating
a new AppDomain (and running RDC.EXE in it). Instead the shell program now
uses Process.Start(...) to launch the RDC.EXE. When RDC.EXE eventually
terminates, the famous DLL does not hang any more and it can be deleted
right away.

My own explanation for this different behaviour is this:

A Win32 process is the owner of a native DLL, not an AppDomain. In the new
scenario two different processes run each one AppDomain, where before one
single process ran both AppDomains. Since the owning process of the native
DLL is now the new process (that dies when RDC.EXE terminates), the DLL is
now freed as planned.

Don't you think this explanation sounds resonable?


Anyway, thank you very much for your participation in my problem - it's
great to have place to ask for help, and hopefully we all got a little bit
wiser.

-Martin.
 
G

Guest

Yes, that's reasonable. The kernel and native loader know nothing about
AppDomains - they are a managed construct. They simply know that a specific
process loaded the DLL. Until it explicitly unloads it (which the CF never
does) or terminates, the OS will keep that module loaded.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com


Martin Christiansen said:
"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com> skrev i en meddelelse news:%[email protected]...
The application won't terminate until all of its threads have exited. If
you are creating threads, you need to take care, before exiting, to close
them all cleanly.

Paul T.

Hi again.

I have now solved problem, and the solution was pretty simple:

I have now changed the shell program not to start the RDC.EXE by creating
a new AppDomain (and running RDC.EXE in it). Instead the shell program now
uses Process.Start(...) to launch the RDC.EXE. When RDC.EXE eventually
terminates, the famous DLL does not hang any more and it can be deleted
right away.

My own explanation for this different behaviour is this:

A Win32 process is the owner of a native DLL, not an AppDomain. In the new
scenario two different processes run each one AppDomain, where before one
single process ran both AppDomains. Since the owning process of the native
DLL is now the new process (that dies when RDC.EXE terminates), the DLL is
now freed as planned.

Don't you think this explanation sounds resonable?


Anyway, thank you very much for your participation in my problem - it's
great to have place to ask for help, and hopefully we all got a little bit
wiser.

-Martin.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top