A Developer WeBLOG RSS 2.0

The past few weeks I’ve been assigned a background task to fix memory leaks issue in our Document Comparison engine. Our document comparison engine was written in Native C++ and ported to Microsoft Visual C++ (not sure if there’s any differences between the two). As a C++ application, our document comparison engine is not managed by .NET framework. It does not have the luxury of having a Garbage Collector to automatically cleaned up all the memory pointers you have created/allocated. In a non-managed code, these memory pointers need to be cleaned manually, or otherwise you’ll be faced by the classic C++ issue: Memory Leaks.

One of the tricky bit in solving memory leaks issue in C++ application is to detect the memory leaks. That is the very first problem that must be solved. I encountered many articles to detect memory leaks, and most of them don’t work. The first article that I tried was this. It was given by my Team Leader, so I assume that this one most probably will work. After few days, I got the constructor overriding of the delete operator working, but seems to stuck in getting the overriding of the new operator to work. I decided to ditch that article to find another one. After trying a couple of other articles, I found that C++ actually has a built in way to debug memory leaks issue.

This makes memory leak detection to be an easy thing to do. All you need to do is to call _CrtDumpMemoryLeaks() function of the crtdbg class. This function will output the list of memory allocations that was created by the application. Cool! But that solved only half of the problem, because now you need to know which object that has not been disposed, in which file and which line was the object created. To solve this problem, we need to override the new operator of DEBUG_NEW and then redefine the DEBUG_NEW. To override the new operator of the debug new, add the following code to your header file:

   1: #ifdef _DEBUG
   2: #include <crtdbg.h>
   3: #define DEBUG_NEW new (_NORMAL_BLOCK, __FILE__, __LINE__)
   4: #else
   5: #define DEBUG_NEW new
   6: #endif

Then you need to add the following line in your cpp file to redefine your DEBUG_NEW:

   1: #ifdef _DEBUG
   2: #define new DEBUG_NEW
   3: #endif

After you add the above two codes, when you call the _CrtDumpMemoryLeaks() function again, it will include the filename and the line in which the code was created. Awesome! Here is an example on how it looks like:

memoryleakdumpexample

Tips: If you’re using Microsoft Visual C++, you can place the codes in your stdafx.h and stdafx.cpp files. That way you do not need to do it in every single file.

RWendi

Tuesday, February 10, 2009 1:36:22 AM UTC |  Comments [2]
c++

I was given a task to port our comparison engine written in native c++ to run in a 64 bit environment. Without modifying anything, I found out that the engine works in 64 bit environment without any problem. But to be compliance, I was still required to get the engine code compiled in the 64 bit compiler. Sounds like an easy task, but it isn't.

The problem is that the engine is compiled using Visual Studio 2003, and VS2003 support for targeting 64 bit environment is pretty much non-existent. Now, I can just convert the solution files to VS2005 or VS 2008 as both of them support multi-platform targeting. I tried that actually and the compiler didn't like the current engine codes, I got lots of compile error. So I reckon by doing that I introduce a whole new set of problems. So that’s not an option.

After some researches, I found a website that suggests that in order to compile VS2003 I have to download "Microsoft Platform SDK". The Platform SDK is an older version of "Microsoft Windows SDK". In there, there's a 64 bit compiler. All you need to do is to change the environment to be 64 bit and then launch VS2003 and specify to use the default environment. Once you've changed the environment, you can't changed it back to target 32 bit without restarting Visual astudio. Thus you need a batch files that will change the environment and launch Visual Studio, which looks like these:

X86 batch file:

call "c:\Program Files\Microsoft Platform SDK\SetEnv.Cmd" /XP32 /Retail
call "dx_setEnv.Cmd" x86
Start "" "c:\Program Files (x86)\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe" /useenv

X64 batch file:

call "c:\Program Files\Microsoft Platform SDK\SetEnv.Cmd" /XP64 /Retail
call "dx_setEnv.Cmd" AMD64
Start "" "c:\Program Files (x86)\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe" /useenv

To confirm you're using the right compiler, you can go to: Tools -> Options -> Projects -> VC++ directories. You will see that the directory now targets the compiler inside the Microsoft Platform SDK folder.

Using the SDK compiler doesn’t work straight away, Im getting the following compile Errors:

error LNK2001: unresolved external symbol __security_cookie
error LNK2019: unresolved external symbol __security_cookie referenced in function _store_winword
error LNK2001: unresolved external symbol __security_check_cookie
error LNK2019: unresolved external symbol __security_cookie referenced in function _store_winword

This is due to the "/GS" switch being set by default by the platform SDK compiler. The code for the "GS" switch resides in the C Runtime Library, which is the default library that is pulled in by the linker in Visual Studio. However, the version of the runtime library included in Platform SDK is not the same as the one in Visual Studio. Thus in order to fix this issue you must include the "bufferoverflowU.lib" in the Project Linker Command Line, i.e Project Properties -> Linker -> Command Line -> Additional Options.

That’s my journey so far in trying to make VS2003 to target 64 bit environment. Still having some issue with the compiler, when it's been resolved will update this post. Anyway, I highly recommend to visit sites on the references, as most of the stuffs written here are coming from there.

Rwendi

References:
http://www.toymaker.info/Games/html/64_bit.html
http://support.microsoft.com/kb/894573

Thursday, October 09, 2008 12:50:51 AM UTC |  Comments [0]
c++ | VS2003
All Content © 2010, RWendi