C++, STL, DLLs, and Buggy Optimizations

STL Add comments

Recently a bug in the STL implementation that comes with Visual C++ 6.0 was brought to my attention. Consider the following function:

typedef std::map<std::string, std::string> map_t;

void f(const map_t& map)
{
    for (map_t::const_iterator iter = map.begin();
         iter != map.end();
         ++iter)
    {
    }
}

For Visual C++ 6.0, if you call f() from within the same EXE or DLL, it works fine, but if calling f() requires you to cross an EXE or DLL barrier, it will fail.

After some debugging, I figured out that this bug is because Visual C++ 6.0’s implementation of std::map, which stores data in a tree structure internally, uses a class static variable to represent a NULL tree node. After putting f() in a separate DLL, the std::map class static value gets initialized to one value in the EXE (on a run on my machine, 0x002f1000) and another value in the DLL (on a run on my machine, 0x003127c0). The ++iter line in the DLL leads to a loop which terminates when it encounters a node it thinks is NULL (0x003127c0). However, as the NULL node was set by the EXE, it has the value 0x002f1000, so the loop within the DLL walks off the tree and crashes.

Per Microsoft Knowledge Base Article 172396: You may experience an access violation when you access an STL object through a pointer or reference in a different DLL or EXE, this is a problem that’s fairly endemic across all of VC++ 6.0 when using STL objects across DLL/EXE barriers. The reason is Microsoft’s STL implementation used class static variables in a number of places to try to avoid storing multiple copies of the same information, but they did not anticipate this DLL-related problem. By the way, this bug is reportedly fixed in Visual C++ 7.

The KB article has a number of suggested workarounds, but I don’t like any of them. Dinkumware, who wrote the Visual C++ 6.0 STL library, has provided a xtree header replacement which fixes the bug by making the value of NULL tree nodes a member of the class rather than a class static variable as part of their Fixes for Library Bugs in VC++ V5.0/V6.0 page, but I don’t like the idea of using third-party compiler header replacements.

My recommendation is to avoid passing STL objects as parameters to DLLs. I also suggest being very careful about using class static variables in your own code.

Comments are closed.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in