Problem with msvcrt60 vs. msvcr71 vs. strdup/free

abkhd at earth.co.jp abkhd at earth.co.jp
Wed Dec 22 14:21:03 EST 2004


From: "" <abkhd at earth.co.jp>
Newsgroups: comp.lang.python
Subject: Re: Problem with msvcrt60 vs. msvcr71 vs. strdup/free
Date: Wed, 22 Dec 2004 11:07:02 -0800

Gerhard Haering wrote:
> Hello,
>
> I used to build Python extension modules with mingw. Now, Python has
> switched to the MSVCR71 runtime with version 2.4, and I thought mingw
> has support for this. But I get problems with symbols being
referenced
> from the wrong DLLs.
>
> You can see the problem by compiling this:
>
> ##################
> #include <string.h>
>
> int main()
> {
>     char* s;
>     int i;
>
>
>     for (i = 0; i < 10; i++) {
>         s = strdup("foo");
>         free(s);
>     }
>
>     return 0;
> }
> ##################
>
> with gcc x.c -lmsvcr71
>
> Then if you run a.exe it crashes.
>
> If you use depends.exe on it, you see that it resolves strdup() via
> msvcrt, but the rest with msvcr71.dll. That's why strdup() is using
> the one malloc, but free() a different free() from the other DLL,
> which is undoubtedly the reason for the crash.
>
> Is there any way I can force mingw to not link in msvcr for things
> like strdup?


Hello


Believe it or not I do not get a crash here.

Using objdump on a.exe I get:

[CUT]

00005014	00005084 00000000 00000000 000052b8 00005100

DLL Name: msvcrt.dll
vma:  Hint/Ord Member-Name Bound-To
51b4	   81  _strdup

00005028	00005090 00000000 00000000 000052f8 0000510c

DLL Name: msvcr71.dll
vma:  Hint/Ord Member-Name Bound-To
51c0	   59  __getmainargs
51d0	   82  __p__environ
51e0	  105  __set_app_type
51f4	  154  _cexit
5200	  211  _fileno
520c	  222  _fmode
5218	  225  _fpreset
5224	  273  _iob
522c	  390  _onexit
5238	  435  _setmode
5244	  599  atexit
5250	  634  free
5258	  715  signal

0000503c	000050cc 00000000 00000000 00005314 00005148

DLL Name: msvcrt.dll
vma:  Hint/Ord Member-Name Bound-To
5264	  510  abort
526c	  537  fflush
5278	  546  fprintf
5284	  603  malloc

00005050	00000000 00000000 00000000 00000000 00000000


[CUT]


Having said that, let me add that I know where you are coming from. And
even though your a.exe did not crash with me now, I know that other
dlls and programs, in my case, did.

And let it be known that unfortunately the measures suggested by the
good people here do not always work. Changing the entry in the specs
file works most  of the time, but not on mmap.pyd (of the official
Python source distribution) for example, where a call to some _lseek of
some sort (I forgot the exact call) is still linked from msvcrt.dll not
from msvcr71. And yes the test_mmap crashes if I compile it that way.

Also changing the specs file seems to work only when the linking is
simple. But if the linking gets complex (as in linking many objects
files to build, say, pythonXY.dll) then even the specs change will not
help. To illustrate, and in trying to get the pyMinGW built Python to
link with msvcr71 that way, one ends up with a pythonXY.dll that
references both runtime libraries: msvcrt, and msvcr71 with strange
consequences. This particular version of Python crashes on  site import
hallucinating about (and I paraphrase!) "Null result from PY...XXX
without Error."

On MSDN, it is stated: "If your DLLs pass CRT resources across the
msvcrt.dll and msvcr71.dll boundary, you will encounter issues with
mismatched CRTs and need to recompile your project with Visual C++
.NET." [1]

I have a gut feeling that "DLLs" here does not mean inter-dll passing
of resources, but intra-dll passing of resources. In other words that
if the self-same DLL uses both run-times then you are in trouble; but I
don't think that this relates to the situation where one DLL is using
msvcrt and another DLL is using msvcr71. Please bear with me.

In this light, I truly don't know why would we try, or recommend
others, to link with libmsvcr71.a, if some mix-up is still possible. I
have yet to see a crash occur when Python24.dll or an extension of the
same uses the old way of  linking with libmsvcrt.a. That way we are
assured that no references are made to msvcr71 when msvcrt is the one
used when linking.

I could be mistaken, but I think people are confusing the behavior of
the MS compilers with MinGW's. The old MS compiler (V. 6) uses
msvcrt.lib by default, and even when the newer MSVS uses the same name
for the its default runtime, that msvcrt link implicitly means the
newer msvcr71 [2]. This behind the scenes behavior is what seems to
have people mixed up. You see if one has older projects compiled using
V. 6, then linking these object files to other object files compiled
with the newer MSVS could effectively mean that the resulting DLL will
have references to both run-times, something by the way is also
mentioned in the MSDN resources [3].

But as far as I know this is not the case with regards to MinGW. MinGW
explicitly uses msvcrt, and so old and newer projects should in theory
have no problems if they stick to msvcrt, as opposed to going the MS
compilers' path-- shooting ourselves in the foot-- and risking linking
to two run-times at the same time.

I have tried changing the specs, and changing the location of msvcr71
and the results are never 100% re-assuring. And so I have resorted to
linking with the good old msvcrt and I have not had a crash due to this
to date. Of course this is my humble experience and I could be mistaken
big time.

For what it is worth, however, my extension DLLs are clean in that they
reference msvcrt only and not msvcr71, and hence all the malloc, and
free and what have you are never shared with any other runtime. My
point being that lacking empirical evidence to the contrary, I think
this is how making extensions to Python 2.4 with MinGW should be: using
the default runtime libmsvcrt.a. It would be fantastic if the good
people at MinGW, or others, can get that hard-wiring issue of the
msvcrt resolved. But until that happens I think it is safer to extend
Python 2.4 the old way. It seems to work fine.



Regards,
Khalid






[1] C-RunTime Libraries from MSDN:
http://tinyurl.com/q20a

[2] Ibid.

[3] Ibid.




More information about the Python-list mailing list