Re: [RFC] Crash sourcing Python script on Windows

Pedro Alves
2011-09-29T10:51:51Z

On Thursday 29 September 2011 05:06:34, Joel Brobecker wrote:
> > FILE is supposed to be an opaque type and as such noone except of
> > the libc which defines it is supposed to "poke" at its internals.
> > however it is common practice in GNU software to assume everybody
> > uses GLIBC and poke around in internal stuff thats not supposed to
> > be accessibly at all in userland.
>
> It could be something simpler than that. Python was built on one
> system, using an unknown build environment. when then use that
> library to link it against some code on a version of Windows that
> is most likely different, with a compiler that is also most likely
> different. If each compiler used a libc where the definition of
> that type is different, then we have an incompatibility.

It is much more likely that your python is linked with a C runtime,
while gdb is linked with another. Try "info sharedlibrary",
and you'll probably see both msvcrXX.dll and both msvcrt.dll loaded.
There's not a single/main C runtime on a Windows system. The C runtime on
Windows is not a central part of the whole system runtime like tradicionally
on Unix. The NT api (and Win32 on top) fills that central role.

There's msvcrt.dll, originally part of Visual C++, but which is bundled
in Windows nowadays (*), and then there's the msvcrtd.dll, the debug variant,
and then Visual Studio will default to link with a different C runtime, and
a different one for each version, going by msvcrXXX.dll names (with XXX
being 70, 80, 90, 100, etc.)

It is common to end up with more than one C runtime loaded
on Windows. Windows dlls are self contained, and all its symbols
must be defined at link-time. There's no symbol interposition
concept in PE.

If you have your application linked with, say, msvcrt.dll, which is
what mingw links with by default, and you load a Dll that was linked
with, say, msvcr70.dll, you'll end up with both C runtimes loaded
in the process. Each of the runtimes will have its own separate
internal state. That's the crux. Given that, you need to be careful to
not pass/use C runtime objects across dlls. E.g., if you malloc
in dll/executable A, you can pass that around to other dlls, but you should
`free' that memory back on dll/executable A, so that the proper runtime
is called. If you had free'd memory in dll B instead (which was linked
against a different runtime, hence you call a different `free' function), B's
C runtime would have no clue what that pointer was -- it's just gargabe from
its perpective, and you'd likely crash.

Same with FILE*, and file descriptions. Each runtime maintains its
own internal state for those.

In a nutshell, your patch is correct.

If such a fix is not always possible, then we'll have to make sure you link
the same runtime in all the offending dlls (those that pass around C
runtime objects).

--
Pedro Alves