Premature .dll loading caused by "Project Dependencies" options

E

Eric Hirst

I have a Visual Studio Solution .sln which contains multiple projects,
including an ODBC driver .dll and a client .exe.

The client .exe is a simple MFC query tool. Nothing I can find in the client
references the driver directly. It uses a connection string to access the
driver, and does not provide this string until the user has filled in a
login dialog.

But when I debug the .exe, I see that the ODBC driver .dll is being loaded
very early, well before InitInstance() is reached. In fact, it's just the
4th item in the load order shown below:

'MyClient.exe': Loaded
'C:\Dev\MyProject\Connector\ODBC\exe\debug\bin\iwinnt\MyClient.exe', Symbols
loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols
loaded.
'MyClient.exe': Loaded
'C:\Dev\Siebel\Connector\ODBC\exe\debug\bin\iwinnt\MyDriver.dll',
Symbolsloaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\version.dll', No symbols loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded.
[etc.]

I can make the behavior go away by either:
(1) Compiling the client in its own, seperate .sln
or:
(2) Going into the .sln's "Project dependencies" dialog and unchecking the
box which makes the .exe dependent on the .dll.

The difference in the compiled result becomes more apparent when I look at
the .map files. When I leave the box unchecked or compile in a separate
..sln, the .map looks like:

0002:00037262 _SQLGetData@24 00459262 f
odbc32:ODBC32.dll
0002:00037268 _SQLDriverConnectW@32 00459268 f
odbc32:ODBC32.dll
0002:0003726e _SQLColumnsW@36 0045926e f
odbc32:ODBC32.dll

and the .dll loads as expected. But when I check the dependency box, it
looks like:

0002:000338ec _SQLGetData@24 004558ec f
oaodbcl:MyDriver.dll
0002:000338f2 _SQLDriverConnectW@32 004558f2 f
oaodbcl:MyDriver.dll
0002:000338f8 _SQLColumnsW@36 004558f8 f
oaodbcl:MyDriver.dll

The upshot of this is that my app crashes when I check the dependency box.
(Why? Not quite sure, there's some 3rd-party code involved, but it looks
like it's because the .dll is allocating some different TLS memory when it's
loaded, memory that becomes bogus by the time MFC tries to log in. This is
independent of a new MFC7.1 bug in the way it calls SQLDriverConnect.)

Is this really by design? This seems like a Visual Studio nmake(?) bug to
me. I don't see anything in the documentation that would imply that a
generated .exe will actually change when you check a Visual Studio Project
dependencies box.

--
Eric Hirst, SSE

Sorry, I don't want to test my company's spam filters.
Please follow up to newsgroup, or send mail to the
following address, which I check occasionally:

s-p-a-r-k-y-d-o-o-d-l-e-d-o-o
y-a-h-o-o
c-o-m
 
E

Eric Hirst

Hm, no response. But I suppose everyone who tried to read the first post
fell asleep long before the punch line, which was, essentially:

"Arranging multiple C++ projects (.vcproj) in a single solution (.sln), then
marking one .vcproj as dependent on another doesn't just affect the build
order. It actually can affect the binaries of the dependent projects,
sometimes causing them to behave in unexpected ways. This bothers me. Does
it bother you too?"

-Eric

Eric Hirst said:
I have a Visual Studio Solution .sln which contains multiple projects,
including an ODBC driver .dll and a client .exe.

The client .exe is a simple MFC query tool. Nothing I can find in the client
references the driver directly. It uses a connection string to access the
driver, and does not provide this string until the user has filled in a
login dialog.

But when I debug the .exe, I see that the ODBC driver .dll is being loaded
very early, well before InitInstance() is reached. In fact, it's just the
4th item in the load order shown below:

'MyClient.exe': Loaded
'C:\Dev\MyProject\Connector\ODBC\exe\debug\bin\iwinnt\MyClient.exe', Symbols
loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols
loaded.
'MyClient.exe': Loaded
'C:\Dev\Siebel\Connector\ODBC\exe\debug\bin\iwinnt\MyDriver.dll',
Symbolsloaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\version.dll', No symbols loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded.
'MyClient.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded.
[etc.]

I can make the behavior go away by either:
(1) Compiling the client in its own, seperate .sln
or:
(2) Going into the .sln's "Project dependencies" dialog and unchecking the
box which makes the .exe dependent on the .dll.

The difference in the compiled result becomes more apparent when I look at
the .map files. When I leave the box unchecked or compile in a separate
.sln, the .map looks like:

0002:00037262 _SQLGetData@24 00459262 f
odbc32:ODBC32.dll
0002:00037268 _SQLDriverConnectW@32 00459268 f
odbc32:ODBC32.dll
0002:0003726e _SQLColumnsW@36 0045926e f
odbc32:ODBC32.dll

and the .dll loads as expected. But when I check the dependency box, it
looks like:

0002:000338ec _SQLGetData@24 004558ec f
oaodbcl:MyDriver.dll
0002:000338f2 _SQLDriverConnectW@32 004558f2 f
oaodbcl:MyDriver.dll
0002:000338f8 _SQLColumnsW@36 004558f8 f
oaodbcl:MyDriver.dll

The upshot of this is that my app crashes when I check the dependency box.
(Why? Not quite sure, there's some 3rd-party code involved, but it looks
like it's because the .dll is allocating some different TLS memory when it's
loaded, memory that becomes bogus by the time MFC tries to log in. This is
independent of a new MFC7.1 bug in the way it calls SQLDriverConnect.)

Is this really by design? This seems like a Visual Studio nmake(?) bug to
me. I don't see anything in the documentation that would imply that a
generated .exe will actually change when you check a Visual Studio Project
dependencies box.

--
Eric Hirst, SSE

Sorry, I don't want to test my company's spam filters.
Please follow up to newsgroup, or send mail to the
following address, which I check occasionally:

s-p-a-r-k-y-d-o-o-d-l-e-d-o-o
y-a-h-o-o
c-o-m
 

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