You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-user@axis.apache.org by Fred Preston <PR...@uk.ibm.com> on 2005/09/23 13:15:58 UTC

/MD and /MT compiler options on MSVC6

Hi All,
        I'd like to discuss the /MD and /MT compiler options available on 
MSVC6.

        The AxisClient DLLs are built with the /MD option that instructs 
the DLLs to use both multi-threaded and DLL specific options within the 
standard header files.  It also tells the compiler to put the MSVCRT.lib 
into the object file and applications are statically linked to it.  The 
DLLs are dynamically linked to msvcprt.lib while still dynamically linked 
to the main C runtime via msvcrt.lib.

        Now, If I use the ant scripts to build one of the tests (such as 
AxisBench) it will build and run successfully.  What I hadn't realised up 
to now is that when I use the ant scripts, it uses the same compiler 
options to build the tests as it does to build the Axis DLLs and so the 
tests are being built with the /MD compiler option.  I am looking at 
AXISCPP-149, trying to work out the best way to clean up the 'delete 
<stub_generatred_object>' problems with complex objects and needed to 
debug a couple of tests to see what is missing in the delete (this is a 
bit of an aside, but helps set the context).  So I created a new MSVC 
project using the test generated framework for AxisBench and compiled the 
project using the 'normal' application build options (i.e. /MT for 
multi-threaded application).  Now, using the /MT option causes the 
compiler to place the LIBCMT.lib into the object file.  When the 'release' 
version of the application was built, it was immediately obvious that I 
had two different exe's because the ant built one was 56K whilst the MSVC 
built one was 208K.  So what does this mean?  Well, I've already said that 
the ant built exe runs, but the MSVC built one with the /MT option failed 
with the following messages:-
Unknown Exception occurred.
Unknown Exception occurred.
Unknown Exception on clean up:
Unknown Exception occurred.
Unknown Exception on clean up:

        It is failing inside 
BenchDataType::Axis_Deserialize_BenchDataType( BenchDataType * param, 
IWrapperSoapDeSerializer * pIWSDZ) at the beginning of the method when it 
tries to delete 'count' which is an object that is passed back after being 
created within the deserialiser (across the DLL boundary? - more on this 
later...).  This is because 'count' is not known to the heap and it 
reports the following error:-
HEAP[AxisBench.exe]: Invalid Address specified to RtlFreeHeap( 00340000, 
0057B2D8)  <-- obviously the numbers will change!

        So, I looked at the compiler options and discovered that ant was 
building the applications with the /MD option.  When I tried this option, 
the exe size was the same and the application ran without a problem.

        So, what does this mean?  I started with the libraries... Looking 
at 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_.2f.MD.2c_2f.ML.2c_2f.MT.2c_2f.LD.asp 
and 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_c_run.2d.time_libraries.asp, 
the LIBCMT.lib is a multi-threaded, static link library and MSVCRT.lib is 
a multi-threaded dynamic link library...  "Humm, so what?", I thought, but 
I kept reading...  The very last sentence of the "What problems exist if 
an application uses both msvcrt and msvcr71?" is very revealing, "...If 
your DLLs pass CRT resources across the library boundary, you will 
encounter issues with mismatched CRTs...".  I would take this to be memory 
issues, such as heap, etc.  And it finishes with "...recompile your 
project with Visual C++ .NET.".

        So, we have potential problems with different libraries using 
MSVC6 and Microsoft is suggesting that if we are finding problems, then we 
need to move to '.NET' which I think implies that we should move to MSVC7 
(which can be found on MSVC 2003 .NET).  Interesting...

RECOMMENDATIONS:
1.      If you are having similar problems as I did running AxisClient, 
try using the /MD rather than /MT compiler flag.
2.      AxisClient should be built using MSVC7 to avoid future library 
inconsistencies.

Regards,

Fred Preston.

Re: /MD and /MT compiler options on MSVC6

Posted by Henrik Nordberg <hn...@sbcglobal.net>.
Hi,

This does not change for MSVC 2003 (7.1), AFAIK. Mixing run time libraries is a bad idea. This is true with GCC and other compilers too.
So the conclusion should not be "if you have trouble with one lib try another", rather it should be "Make sure you use the same run-time lib in all modules in your app, and make sure resources allocated in one RT are freed with the same RT.".
The problem is similar to allocating memory using operator new and freeing it with free(). Those implementations must match or you will have undefined behavior (which hopefully leads to a crash during development so you can fix it).

 - Henrik
  ----- Original Message ----- 
  From: Fred Preston 
  To: axis-c-dev@ws.apache.org ; axis-c-user@ws.apache.org 
  Sent: Friday, September 23, 2005 4:15 AM
  Subject: /MD and /MT compiler options on MSVC6



  Hi All, 
          I'd like to discuss the /MD and /MT compiler options available on MSVC6. 

          The AxisClient DLLs are built with the /MD option that instructs the DLLs to use both multi-threaded and DLL specific options within the standard header files.  It also tells the compiler to put the MSVCRT.lib into the object file and applications are statically linked to it.  The DLLs are dynamically linked to msvcprt.lib while still dynamically linked to the main C runtime via msvcrt.lib. 

          Now, If I use the ant scripts to build one of the tests (such as AxisBench) it will build and run successfully.  What I hadn't realised up to now is that when I use the ant scripts, it uses the same compiler options to build the tests as it does to build the Axis DLLs and so the tests are being built with the /MD compiler option.  I am looking at AXISCPP-149, trying to work out the best way to clean up the 'delete <stub_generatred_object>' problems with complex objects and needed to debug a couple of tests to see what is missing in the delete (this is a bit of an aside, but helps set the context).  So I created a new MSVC project using the test generated framework for AxisBench and compiled the project using the 'normal' application build options (i.e. /MT for multi-threaded application).  Now, using the /MT option causes the compiler to place the LIBCMT.lib into the object file.  When the 'release' version of the application was built, it was immediately obvious that I had two different exe's because the ant built one was 56K whilst the MSVC built one was 208K.  So what does this mean?  Well, I've already said that the ant built exe runs, but the MSVC built one with the /MT option failed with the following messages:- 
  Unknown Exception occurred. 
  Unknown Exception occurred. 
  Unknown Exception on clean up: 
  Unknown Exception occurred. 
  Unknown Exception on clean up: 

          It is failing inside BenchDataType::Axis_Deserialize_BenchDataType( BenchDataType * param, IWrapperSoapDeSerializer * pIWSDZ) at the beginning of the method when it tries to delete 'count' which is an object that is passed back after being created within the deserialiser (across the DLL boundary? - more on this later...).  This is because 'count' is not known to the heap and it reports the following error:- 
  HEAP[AxisBench.exe]: Invalid Address specified to RtlFreeHeap( 00340000, 0057B2D8)  <-- obviously the numbers will change! 

          So, I looked at the compiler options and discovered that ant was building the applications with the /MD option.  When I tried this option, the exe size was the same and the application ran without a problem. 

          So, what does this mean?  I started with the libraries... Looking at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_.2f.MD.2c_2f.ML.2c_2f.MT.2c_2f.LD.asp and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_c_run.2d.time_libraries.asp, the LIBCMT.lib is a multi-threaded, static link library and MSVCRT.lib is a multi-threaded dynamic link library...  "Humm, so what?", I thought, but I kept reading...  The very last sentence of the "What problems exist if an application uses both msvcrt and msvcr71?" is very revealing, "...If your DLLs pass CRT resources across the library boundary, you will encounter issues with mismatched CRTs...".  I would take this to be memory issues, such as heap, etc.  And it finishes with "...recompile your project with Visual C++ .NET.". 

          So, we have potential problems with different libraries using MSVC6 and Microsoft is suggesting that if we are finding problems, then we need to move to '.NET' which I think implies that we should move to MSVC7 (which can be found on MSVC 2003 .NET).  Interesting... 

  RECOMMENDATIONS: 
  1.        If you are having similar problems as I did running AxisClient, try using the /MD rather than /MT compiler flag. 
  2.        AxisClient should be built using MSVC7 to avoid future library inconsistencies. 

  Regards,

  Fred Preston.