Strange behavior of VM with Delphi COM Servers. 
Author Message
 Strange behavior of VM with Delphi COM Servers.

Hi,

I've been tracking for some time an access violation on process
termination when using an in-process COM Server written in delphi from
the Dolphin VM.  This problem is only present when executing the
Lagoon-deployed exe, as when working with the development environment
the COM Server doesn't seem to be freed. What I've concluded is that
there is something unusual with the contexts under which the DllMain
procedure is called (under Delphi this procedure is called _InitLib in
unit sysinit.pas). One of the parameters of this proc is dfwReason
which takes the values: (DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH,
DLL_THREAD_ATTACH, DLL_THREAD_DETACH).
I've created a barebones COM Server, and deployed a Dolphin app which
only had a SessionManager subclass whose instance just created an
instance from this server. After tracing through the DllMain calls I
raliably get this sequence:
Call 1 -  fdwReason = DLL_PROCESS_ATTACH   (GetCurrentThreadID -> n1)
Call 2 -  fdwReason = DLL_THREAD_ATTACH   (GetCurrentThreadID -> n2)
Call 3 -  fdwReason = DLL_THREAD_DETACH   (GetCurrentThreadID -> n1)
Call 4 -  fdwReason = DLL_PROCESS_DETACH   (GetCurrentThreadID -> n1)

So, it would seem that the thread for the first detach is the wrong
one. And this causes an exception because Delphi tries to free a TLS
allocated memory twice, or tries to access a threadvar after the first
detach in the context of that thread. I've worked around the problem
touching the base Delphi RTL kernel, but I don't think this is a good
idea in the long run. Does anyone  happen to know why does this
strange context sequence happen?
I assume the Dolphin VM has something to do with this because when
creating a COM client in Delphi calls 2 and 3 are never made.

If anyone wants to take a look I can send the barebones projects that
reproduces the problem.

thanks
Juan Vidal Pich



Tue, 29 Jun 2004 21:21:55 GMT  
 Strange behavior of VM with Delphi COM Servers.
Juan


Quote:

> I've been tracking for some time an access violation on process
> termination when using an in-process COM Server written in Delphi from
> the Dolphin VM.  This problem is only present when executing the
> Lagoon-deployed exe, as when working with the development environment
> the COM Server doesn't seem to be freed. What I've concluded is that
> there is something unusual with the contexts under which the DllMain
> procedure is called (under Delphi this procedure is called _InitLib in
> unit sysinit.pas). One of the parameters of this proc is dfwReason
> which takes the values: (DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH,
> DLL_THREAD_ATTACH, DLL_THREAD_DETACH).
> I've created a barebones COM Server, and deployed a Dolphin app which
> only had a SessionManager subclass whose instance just created an
> instance from this server. After tracing through the DllMain calls I
> raliably get this sequence:
> Call 1 -  fdwReason = DLL_PROCESS_ATTACH   (GetCurrentThreadID -> n1)
> Call 2 -  fdwReason = DLL_THREAD_ATTACH   (GetCurrentThreadID -> n2)
> Call 3 -  fdwReason = DLL_THREAD_DETACH   (GetCurrentThreadID -> n1)
> Call 4 -  fdwReason = DLL_PROCESS_DETACH   (GetCurrentThreadID -> n1)

> So, it would seem that the thread for the first detach is the wrong
> one. And this causes an exception because Delphi tries to free a TLS
> allocated memory twice, or tries to access a threadvar after the first
> detach in the context of that thread. I've worked around the problem
> touching the base Delphi RTL kernel, but I don't think this is a good
> idea in the long run. Does anyone  happen to know why does this
> strange context sequence happen?

Well ultimately it is up to Windows how it calls DllMain. I'm not sure how
Dolphin could cause it to wrongly call DllMain with both DLL_THREAD_DETACH
and DLL_PROCESS_DETACH for the same thread.

The Win32 help states that "A thread calling the DLL entry-point function
with DLL_PROCESS_ATTACH does not call the DLL entry-point function with
DLL_THREAD_ATTACH" (so you wouldn't expect a DLL_THREAD_ATTACH for n1), and
that "... there are cases in which the entry-point function is called for a
terminating thred even if the DLL never attached to the thread..." (?), and
"Note that the thread that receives the DLL_PROCESS_DETACH notification is
not necessarily the same thread that received the DLL_PROCESS_ATTACH
function." Lastly, "When a DLL is unloaded from a process as a result of an
unsuccessful load of the DLL, termination of the process, or a call to
FreeLibrary, the system does not call the DLL's entry point function with
the DLL_THREAD_DETACH value for the individual theads of the process. The
DLL is only sent a DLL_PROCESS_DETACH notification."

Considering how loosely it is all specified, I'm not sure the sequence of
calls you list above is necessarily invalid (although common sense suggests
it is wrong). Even if it is, it is not necessarily in Dolphin's direct
control. Dolphin creates threads directly, and indirectly via the use of
certain Windows APIs (e.g. the multimedia timer), so there will be multiple
threads, some of which may have been created before the COM server has been
loaded, and some not. Other components and APIs are also free to create
their own threads. These threads may not be terminated in the same order
they were created.

Quote:
> I assume the Dolphin VM has something to do with this ...

Certainly the conditions created by the Dolphin VM may have something to do
with this, but I'm not convinced it is directly responsible. Dolphin may
create and terminate threads, but it is up to Windows to call DllMain.
Alternative causes might be an obscure bug in Windows (have you tried using
NT/2k vs Win9X?), or perhaps Delphi's library is not defensively enough
coded to handle the unpredictable ordering.

Quote:
>...because when
> creating a COM client in Delphi calls 2 and 3 are never made.

Does your Delphin COM client have more than one thread?

Regards

Blair



Fri, 02 Jul 2004 23:35:21 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Windows/COM events/strange behavior

2. socket -server Server xxxx Behavior

3. how to register COM interface from python COM-server

4. Unable to use win32com on Ecco COM server despite success with VB and Perl COM

5. Catch COM events generated by a Python COM server with Visual Basic

6. Can't See My COM Server in COM Browser

7. Fortran numerical server using Com server wizard.

8. COM server in python - howto restart server

9. Strange lockup: Delphi - DVF DLL

10. Strange instance class valiable behavior

11. AXValueConvertingControlSite strange behavior

12. Strange news groups behavior

 

 
Powered by phpBB® Forum Software