90 likes | 183 Views
CRT State Stuff. Dana Robinson The HDF Group. In the next slide, I show a single executable linked to three dlls . Two dlls and the executable were built with Visual Studio 2010 (linked to MSVCR100.dll). One dll was built with VS2008 (linked to MSVCR90.dll)
E N D
CRT State Stuff Dana Robinson The HDF Group
In the next slide, I show a single executable linked to three dlls. Two dllsand the executable were built with Visual Studio 2010 (linked to MSVCR100.dll). One dll was built with VS2008 (linked to MSVCR90.dll) Note how there are two CRT states, one per library. If the program gets memory from dll #1 and passes it to dll #2 for freeing, there will be heap corruption in both CRTs. This can result in very hard to track down memory bugs. As far as I can tell, the OS doesn't complain because, at the Win32 level, the process owns the memory so there's no problem. The problem is that bookkeeping data in the CRTs is not updated (or incorrectly updated) in the libraries. Also note that we could replace MSVCR90.dll with MSVCR100d.dll (the debug library) and we'd have the same issue since they are also separate dlls. This is why you shouldn't mix debug and release libraries.
Program (*.exe) dll #1 dll #3 dll #2 MSVCR90.dll MSVCR100.dll S S S CRT state #1 S CRT state #2
In the next slide, I show what I *think* you assume static linking is like. Correct me if I'm wrong! In this figure, there is a single program that is linked to the same three libraries, this time statically. Library #1 is still compiled with VS2008 and the other libraries and executable are compiled with VS2010. Everything is statically linked, both the executable to the libraries and the libraries to the runtime. The executable is also statically linked to the CRT. I have drawn dashed lines around the libraries to indicate that they are an internal part of the executable and can somehow share state. This is NOT a correct picture of the CRT state situation!
Program (*.exe) lib #1 lib #2 lib #3 S S Internal shared CRT state
In the next slide, I show the actual situation when you statically link multiple libraries on Windows. As in the previous figure, there is a single program that is statically linked to the same three libraries, which are, in turn, statically linked to the CRTs. There are now FOUR runtime states so the problem is WORSE. In the shared linkage example (slide #3), we could freely pass CRT objects between dlls #2 and #3 as well as the executable since they share state. dll #1 was the only one we had to worry about. Now we can't pass CRT objects like memory and file handles between any library without risking issues. This is why static linking on Windows is a very bad idea.
Program (*.exe) S lib #1 lib #2 lib #3 S S S S CRT state #1 (based on MSVCR90) S CRT state #3 (based on MSVCR100) S CRT state #2 (based on MSVCR100) S CRT state #4 (based on MSVCR100)
Why is this so? A static link to a library just copies the library code into the executable or library being built. Here's what happens when we build one of our libraries: copy MSVCR100.lib lib #2 The compiler copies all CRT code required for the functions you need, including the CRT state stuff!
So when we build a second library, that code is copied over a second time. i.e., state variable foo in library 2 maps to a different location in memory than state variable foo in library 3. lib #2 MSVCR100.lib copy lib #3 MSVCR100.lib copy There is NO shared state! Static linking exacerbates the problem of CRT states. It does NOT fix it.