From: Robert Oschler on
I have a MSVC 6.x application that is used by a Delphi 6 application. The
MSVC DLL is being loaded dynamically using LoadLibrary().

For debugging purposes, I put code in the MSVC DLL that counts each
occurrence of DLL_THREAD_ATTACH & DLL_THREAD_DETACH using a static integer
counter.

I am seeing the following strange behavior when I run the Delphi app as the
debugger target for the MSVC DLL project, in the IDE:

DLL_THREAD_ATTACH is called many times as the application is starting up.

DLL_THREAD_ATTACH & DLL_THREAD_DETACH seems to be called each time I open
and close the wave device. This is really strange because the code that
opens and closes the wave devices is *in the Delphi app* and not the MSVC
DLL and should not have an effect on the MSVC DLL.

In all cases the parent process shown by the MSVC call stack
(OutputDebugString results) is DllMain, then _DLLMainCrtStartup, then a few
NTDLL calls above that.

I have included the debug monitor output below. A couple of notes about the
output:

- Any message that is preceded by '***' are coming from the Delphi app.
- The intializeEngine, beginUtterance, endUtterance, and any message
preceded by "VServer1" are coming from my MSVC DLL.
- All other messages are either DLL "Loaded" messages or messages from other
DLL's that my app uses.

This is really strange. What could be causing this and how can I fix it?

Thanks
Robert

---------------- DEBUG MONITOR OUTPUT -------------

Loaded 'C:\Projects_Delphi_OSDN\MusicVox\voxtail.exe', no matching symbolic
information found.
Loaded 'C:\WINNT\system32\ntdll.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\KERNEL32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\USER32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\GDI32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\ADVAPI32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\rpcrt4.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\OLEAUT32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\OLE32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\version.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\lz32.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\comctl32.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\WINSPOOL.DRV', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\mpr.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\SHELL32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\SHLWAPI.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\msvcrt.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\COMDLG32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wsock32.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\ws2_32.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\ws2help.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\winmm.dll', no matching symbolic information
found.
Preloaded symbols may not match
'C:\Projects_Delphi_OSDN\MusicVox\sphinx\vserver1.dll'.
Loaded symbols for 'C:\WINNT\system32\MSVCRTD.DLL'
Loaded 'C:\WINNT\system32\serwvdrv.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\umdmxfrm.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\ctwdm32.dll', no matching symbolic information
found.
LoadEnableFound one versionOpenCloseDisableFreeVServer1 DLL_PROCESS_ATTACH
called(1).
Loaded 'C:\Program Files\ScanSoft\OmniPagePro11.0\ophook32.dll', no matching
symbolic information found.
Loaded 'C:\WINNT\system32\OLEPRO32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\clbcatq.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(1).
Loaded 'C:\WINNT\system32\SHDOCVW.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\WININET.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\CRYPT32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\msasn1.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(2).
Loaded 'C:\WINNT\system32\riched32.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\riched20.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\uuirtdrv.dll', no matching symbolic information
found.
UUIRTOpen: ThreadID = 000006b4
Creating New Global Set!
Loaded 'C:\WINNT\system32\FTD2XX.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\SETUPAPI.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\USERENV.DLL', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(3).
Starting IRThread
VServer1 DLL_THREAD_ATTACH called(4).
Now taking over dispatch ownership!
VServer1 DLL_THREAD_ATTACH called(5).
***
============================================================================
Dispatch: TransmitIR
PAUSE
RESUME
*** doStopCommand Executed.
*** WM_PLAY_HAS_ENDED message sent(2).
*** (SphinxLink) Calling Load Library.
*** (SphinxLink) Assigning function pointers.
initializeEngine() called.
Loaded 'C:\WINNT\system32\shdoclc.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\URLMON.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\mlang.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(6).
Loaded 'C:\WINNT\system32\msafd.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wshtcpip.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(7).
Loaded 'C:\WINNT\system32\RASAPI32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\RASMAN.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\TAPI32.DLL', no matching symbolic information foun
d.
Loaded 'C:\WINNT\system32\rtutils.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(8).
Loaded 'C:\WINNT\system32\sensapi.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\NETAPI32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\secur32.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\ntdsapi.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\dnsapi.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\WLDAP32.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\netrap.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\samlib.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\RSABASE.DLL', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(9).
Loaded 'C:\WINNT\system32\RNR20.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\IPHLPAPI.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\icmp.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\mprapi.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\activeds.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\adsldpc.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\DHCPCSVC.DLL', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\winrnr.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\rasadhlp.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(10).
Loaded 'C:\WINNT\system32\MSHTML.DLL', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(11).
VServer1 DLL_THREAD_ATTACH called(12).
Loaded 'C:\WINNT\system32\msls31.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\imm32.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(13).
Loaded 'C:\WINNT\system32\cscui.dll', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\cscdll.dll', no matching symbolic information
found.
beginUtterance() called.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(14).
Loaded 'C:\WINNT\system32\msacm32.drv', no matching symbolic information
found.
Loaded 'C:\WINNT\system32\msacm32.dll', no matching symbolic information
found.
VServer1 DLL_THREAD_ATTACH called(15).
*** Wave Device Opened.
endUtterance() called.
beginUtterance() called.
VServer1 DLL_THREAD_DETACH called(1).
The thread 0x900 has exited with code 0 (0x0).
*** Wave Device Closed.
endUtterance() called.
VServer1 DLL_THREAD_ATTACH called(16).
*** Wave Device Opened.
VServer1 DLL_THREAD_DETACH called(2).
The thread 0x4B0 has exited with code 0 (0x0).
First-chance exception in voxtail.exe (KERNEL32.DLL): 0x0EEDFADE: (no name).
*** Wave Device Closed.



From: Alex Blekhman on
Robert Oschler wrote:
> I am seeing the following strange behavior when I run the
> Delphi app as the debugger target for the MSVC DLL
> project, in the IDE:
>
> DLL_THREAD_ATTACH is called many times as the application
> is starting up.
>
> DLL_THREAD_ATTACH & DLL_THREAD_DETACH seems to be called
> each time I open and close the wave device. This is
> really strange because the code that opens and closes the
> wave devices is *in the Delphi app* and not the MSVC DLL
> and should not have an effect on the MSVC DLL.

That's not strange at all. When new thread is created or
existing thread exits, then *all* loaded DLLs are notified
with DLL_THREAD_ATTACH/DETACH.


From: Robert Oschler on

"Alex Blekhman" <tkfx^N05P4M^@yahoo.com> wrote in message
news:3eb88aF24tchU1(a)individual.net...
> That's not strange at all. When new thread is created or
> existing thread exits, then *all* loaded DLLs are notified
> with DLL_THREAD_ATTACH/DETACH.
>
>

Ok, that makes sense. I thought a DLL_THREAD_ATTACH/DETACH message meant
*my DLL's* thread was being attached or detached.

What use is it to know when a new thread is created that doesn't really
affect your DLL? I'm guessing the new thread that is being repeatedly
recreated is the Wave device thread, created by the Windows multimedia DLL
when I open and close the wave device.

I'm still having trouble getting my DLL to fully unload when I call
FreeLibrary(). I'm guessing someone or something is increasing the DLL
reference count beyond 1, but I still haven't figured out what. I was
hoping that this DLL_THREAD_ATTACH/DETACH behavior was related, but if I
understand you correctly, it's not.

Thanks,
Robert


From: Alex Blekhman on
Robert Oschler wrote:
> Ok, that makes sense. I thought a
> DLL_THREAD_ATTACH/DETACH message meant *my DLL's* thread
> was being attached or detached.

Actually, DLL doesn't have any thread. It's just loaded into
procerss address space. Then any thread can run code from
the DLL.

> What use is it to know when a new thread is created that
> doesn't really affect your DLL?

Some libraries want to store thread specific data, so calls
from one thread won't affect state of library for other
threads. These libraries usually use Thread Local Storage
(TLS) functions in DLL_THREAD_ATTACH/DETACH case. For
example, CRT implementation of strtok() function relies on
TLS, so you can call it from different threads.

> I'm still having trouble getting my DLL to fully unload
> when I call FreeLibrary().

Do you do something wicked on DLL_PROCESS_DETACH
notification?


From: Tim Kannel on
> That's not strange at all. When new thread is created or
> existing thread exits, then *all* loaded DLLs are notified
> with DLL_THREAD_ATTACH/DETACH.

.... except DLLS referenced in calls to DisableThreadLibraryCalls()


--
Tim Kannel

TCAP - Captures console I/O to a file (DOS,Win9x)
http://www.simtel.net/pub/pd/11141.shtml