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