Over the past couple of days I plunged into our product suite (see http://www.kronos.com/Products/TotalCare.htm) to look for memory leaks and check for any code smells (an Agile term). I remembered back to the good old days when I would use memproof under BCB6 and quickly find and fix my issues, alas in BDS2006 I had no such success. Memproof has not been updated to support BDS2006 so I checked out what my options were. Ultimately I ended up compiling all our packages, application and workspace plugin dll’s under Codeguard which is built into BDS2006. In some ways codeguard is good and in other ways it is aweful. One particular situation to note was that during application exit, the program would crash with an access violation error. This would ONLY happen when one of the plugin DLL’s was fully loaded. Codeguard would not tell me what the problem was but gave me a clue… the clue was the CPU window showed that recently the c++ runtime library was unloading. After many recompiles and compiler setting changes… somehow.. i am not sure.. I think it was a fluke.. but codeguard stopped on a line of code during the access violation! Wonderful! Here was the code:
void __fastcall MyFunc()
out1 << “myField = ” << iID << ends;
AnsiString asFilter = out1.str();
Now i have simplified the code but in essence the ostrstream object was the cause of the crash. I noticed this posting on google: http://groups.google.ca/group/borland.public.cppbuilder.ide/browse_thread/thread/caaee99d8be8d0bf/d77d653639e82abd?lnk=st&q=ostrstream+bug&rnum=3&hl=en#d77d653639e82abd
which at some point mentiones:
“Also, is there any reason why you’re not using ostringstream, since
the strstream classes are depreicated?
If you need to use the strstream class, note that you’re leaking
memory, since you’re responsible for deleting (delete) the pointer
returned by the call to str().)”
So the fact that this DLL was leaking memory had caused a crash at application shutdown.. and to “mask” the problem someone has changed the linker options for that DLL and disabled Use Dynamic RTL.
Instead of “cleaning up” after the .str() calls I replaced the filter statements with typical AnsiString.sprintf()’s and voila… compile the DLL using dynamic RTL and no more crash on exit. It always troubles me when a workaround is used which nobody knows why it was used 🙂 Now we know what was going on and it was fixed. One thing I have found out about Codeguard… it is somewhat unwieldy to use but almost always is correct in telling you “something is wrong” just not any more detail than that.