From: "" <[EMAIL PROTECTED]> 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. -- http://mail.python.org/mailman/listinfo/python-list