Saturday, April 10, 2010

Handle Leak, Memory Leak

How to Collect Information for Handle Leak Issues in Process Space for Post-mortem Analysis Click here!!!

Memory Leak Detection Using Windbg Click here!!!

Visual Leak Detector - Enhanced Memory Leak Detection for Visual C++ Click hete!!!

Thursday, April 8, 2010

Conversion between Unicode UTF-16 and UTF-8

There are several possible representations of Unicode text, e.g. UTF-8, UTF-16, UTF-32, etc.

UTF-16 is the default Unicode encoding form used by Windows.

UTF-8 is a common encoding form used to exchange text data on the Internet.
One of the advantages of UTF-8 is that there is no endian problem (i.e. big-endian vs. little-end), because UTF-8 is interpreted just as a sequence of bytes (instead, it is important to specify the correct endiannes of UTF-16 and UTF-32 code units).


//----------------------------------------------------------------------------

// FUNCTION: ConvertUTF8ToUTF16

// DESC: Converts Unicode UTF-8 text to Unicode UTF-16 (Windows default).

//----------------------------------------------------------------------------

wstring ConvertUTF8ToUTF16( IN const string& szTextUTF8)

{

//

// Special case empty input string

//

if(0 == szTextUTF8.length())

{

return L"";

}


//

// Get size of destination UTF-16 buffer, in WCHAR's

//

int cchUTF16 = ::MultiByteToWideChar(

CP_UTF8, // convert from UTF-8

MB_ERR_INVALID_CHARS, // error on invalid chars

szTextUTF8.c_str(), // source UTF-8 string

szTextUTF8.length() + 1,// total length of source UTF-8 string,

// in CHAR's (= bytes), including end-of-string \0

NULL, // unused - no conversion done in this step

0 // request size of destination buffer, in WCHAR's

);


assert( cchUTF16 != 0 );


if ( cchUTF16 == 0 )

{

stringstream ssError;

ssError << "Error in " <<>

OutputDebugStringA(ssError.str().c_str());

return L"";

}

//

// Allocate destination buffer to store UTF-16 string

//

WCHAR * pszUTF16 = new WCHAR[cchUTF16];

//

// Do the conversion from UTF-8 to UTF-16

//

int result = ::MultiByteToWideChar(

CP_UTF8, // convert from UTF-8

MB_ERR_INVALID_CHARS, // error on invalid chars

szTextUTF8.c_str(), // source UTF-8 string

szTextUTF8.length() + 1, // total length of source UTF-8 string,

// in CHAR's (= bytes), including end-of-string \0

pszUTF16, // destination buffer

cchUTF16 // size of destination buffer, in WCHAR's

);


assert( result != 0 );

if ( result == 0 )

{

stringstream ssError;

ssError << "Error in " <<>

OutputDebugStringA(ssError.str().c_str());

}

wstring str(pszUTF16);


delete [] pszUTF16;


// Return resulting UTF16 string

return str;

}


//----------------------------------------------------------------------------

// FUNCTION: ConvertUTF16ToUTF8

// DESC: Converts Unicode UTF-16 (Windows default) text to Unicode UTF-8.

//----------------------------------------------------------------------------

string ConvertUTF16ToUTF8( IN const wstring& szTextUTF16 )

{

//

// Special case of NULL or empty input string

//

if ( 0 == szTextUTF16.length() )

{

// Return empty string

return "";

}

//

// WC_ERR_INVALID_CHARS flag is set to fail if invalid input character

// is encountered.

// This flag is supported on Windows Vista and later.

// Don't use it on Windows XP and previous.

//

#if (WINVER >= 0x0600)

DWORD dwConversionFlags = WC_ERR_INVALID_CHARS;

#else

DWORD dwConversionFlags = 0;

#endif

//

// Get size of destination UTF-8 buffer, in CHAR's (= bytes)

//

int cchUTF8 = ::WideCharToMultiByte(

CP_UTF8, // convert to UTF-8

0, // specify conversion behavior

szTextUTF16.c_str(), // source UTF-16 string

szTextUTF16.length() + 1, // total source string length, in WCHAR's,

// including end-of-string \0

NULL, // unused - no conversion required in this step

0, // request buffer size

NULL, NULL // unused

);

assert( cchUTF8 != 0 );

if ( cchUTF8 == 0 )

{

stringstream ssError;

ssError << "Error in " <<>

OutputDebugStringA(ssError.str().c_str());

return "";

}

//

// Allocate destination buffer for UTF-8 string

//

CHAR * pszUTF8 = new CHAR[cchUTF8];

//

// Do the conversion from UTF-16 to UTF-8

//

int result = ::WideCharToMultiByte(

CP_UTF8, // convert to UTF-8

0, // specify conversion behavior

szTextUTF16.c_str(), // source UTF-16 string

szTextUTF16.length() + 1, // total source string length, in WCHAR's,

// including end-of-string \0

pszUTF8, // destination buffer

cchUTF8, // destination buffer size, in bytes

NULL, NULL // unused

);


assert( result != 0 );

if ( result == 0 )

{

stringstream ssError;

ssError << "Error in " <<>

OutputDebugStringA(ssError.str().c_str());

}

string str(pszUTF8);

delete [] pszUTF8;

// Return resulting UTF-8 string

return str;

}

References: UTF-8, UTF-16, UTF-32 & BOM

Friday, April 2, 2010

Singleton Class using shared_ptr

Hi All,

Today I have come across one class called shared_ptr which has one good constructor which can accept function pointer. This function will be called by destructor of shared_ptr. Hence this function can be used for releasing SINGLETON CLASS REFERENCE.

Lets see the code:-

Singleton.h

#ifndef __SINGLETON__
#define __SINGLETON__

namespace myapp
{
class SingletonPattern
{
public:
static SingletonPattern* GetInstance();
void Release();
private:
SingletonPattern();
SingletonPattern(const SingletonPattern&);
~SingletonPattern();
SingletonPattern& operator =(const SingletonPattern&);
private:
static SingletonPattern* m_pSinglePattern;
static int m_Count;
};

void Release(SingletonPattern* obj);
};

#endif //__SINGLETON__

Singleton.cpp


#include "stdafx.h"

#include "Singleton.h"

using namespace myapp;

SingletonPattern* SingletonPattern::m_pSinglePattern = NULL;
int SingletonPattern::m_Count=0;

SingletonPattern::SingletonPattern()
{
}

SingletonPattern::SingletonPattern(const SingletonPattern &)
{
}

SingletonPattern::~SingletonPattern()
{
}

SingletonPattern& SingletonPattern::operator =(const SingletonPattern& rhs)
{
if (this != &rhs) {
// Deallocate, allocate new space, copy values...
}
return *this;
}

SingletonPattern* SingletonPattern::GetInstance()
{
if(NULL == m_pSinglePattern)
{
m_pSinglePattern = new SingletonPattern;
}

m_Count++;

return m_pSinglePattern;
}

void SingletonPattern::Release()
{
if(m_Count > 0) --m_Count;
if(NULL != m_pSinglePattern && 0 == m_Count)
{
delete m_pSinglePattern;
m_pSinglePattern = NULL;
}
}

void myapp::Release(SingletonPattern* obj)
{
if(NULL != obj) obj->Release();
}

SingletonTest.cpp

Main Function

#include "stdafx.h"

#include "vld.h"

#include "Singleton.h"

using namespace myapp;

using namespace std::tr1;

int _tmain(int argc, _TCHAR* argv[])
{
shared_ptr objshared(SingletonPattern::GetInstance(), Release);

shared_ptr objshared1(SingletonPattern::GetInstance(), Release);

return 0;
}

Singleton class reference will be release automatically when destructor of shared_ptr class is called.

Hence when main function is about to finish, shared_ptr destructor will be called and finally release function will be called.

We neednot have call Release explicitly for singleton class.

We cannot use auto_ptr because there is no such constructor which accepts function pointer.

Monday, March 29, 2010

Exception Handing

What is the output of the following program?

CRITICAL_SECTION g_cs;

int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
OutputDebugStringA("Inside Filter Function");
if (code == EXCEPTION_ACCESS_VIOLATION)
{
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}


int _tmain(int argc, _TCHAR* argv[])
{
__try
{
__try
{
__try
{
EnterCriticalSection(&g_cs);
}
__finally
{
OutputDebugStringA("inner\n");
}
}
__finally
{
OutputDebugStringA("outer\n");
}
}
__except(EXCEPTION_EXECUTE_HANDLER/*filter(GetExceptionCode(), GetExceptionInformation())*/)
{
OutputDebugStringA("Got the exception\n");
}

return 0;
}

Answer:

Inside Filter function
Inner
Outer
Got the exception

Summary:

Whenever exception happens it searches for very first __except irrespective of any number of __finally block in between(like above) and then it executes very first finally block and soon...

Why exception has occurred in above code?
Ans: We have not called InitializeCriticalSection().

Where are variables stored?

Local Variables - Stack
Register variables - Register
Global & static variables - data segment.
dynamically created memory - Heap
C program instructions get stored - code segment
extern variables - data segment.

Tuesday, March 23, 2010

Argument of KiUserExceptionDispatcher() function

For hardware generated exceptions (such as access violations), one can look for ntdll!KiUserExceptionDispatcher on the stack, which takes a PCONTEXT and PEXCEPTION_RECORD as argument.

Stack Trace:

0021e9fc 77db5f79 fffffffe 0021f878 0021eb04 ntdll!_except_handler4+0x8e

0021ea20 77db5f4b 0021eae8 0021f878 0021eb04 ntdll!ExecuteHandler2+0x26

0021ead0 77db5dd7 0121eae8 0021eb04 0021eae8 ntdll!ExecuteHandler+0x24

0021ead0 77d8e13d 0121eae8 0021eb04 0021eae8 ntdll!KiUserExceptionDispatcher+0xf

0021ee20 77d8e04d 00000000 00000000 00000001 ntdll!RtlpWaitOnCriticalSection+0xc5

0:000> .exr 0x21eae8

ExceptionAddress: 77d8e13d (ntdll!RtlpWaitOnCriticalSection+0x000000c5)

ExceptionCode: c0000005 (Access violation)

ExceptionFlags: 00000000

NumberParameters: 2

Parameter[0]: 00000001

Parameter[1]: 00000014

Attempt to write to address 00000014

0:000> .cxr 0x21eb04

eax=00000000 ebx=fffffffc ecx=00000000 edx=00000004 esi=737b19a0 edi=737b19a4

eip=77d8e13d esp=0021edd0 ebp=0021ee20 iopl=0 nv up ei pl nz ac po cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010213

ntdll!RtlpWaitOnCriticalSection+0xc5:

77d8e13d 83401401 add dword ptr [eax+14h],1 ds:0023:00000014=????????

0:000> dt -r1 0x21eb04 CONTEXT
ntdll!CONTEXT
+0x000 ContextFlags : 0x1003f
+0x004 Dr0 : 0
+0x008 Dr1 : 0
+0x00c Dr2 : 0
+0x010 Dr3 : 0
+0x014 Dr6 : 0
+0x018 Dr7 : 0
+0x01c FloatSave : _FLOATING_SAVE_AREA
   +0x000 ControlWord : 0xffff027f
   +0x004 StatusWord : 0xffff0000
   +0x008 TagWord : 0xffffffff
   +0x00c ErrorOffset : 0
   +0x010 ErrorSelector : 0
   +0x014 DataOffset : 0
   +0x018 DataSelector : 0xffff0000
   +0x01c RegisterArea : [80] ""
   +0x06c Cr0NpxState : 0
+0x08c SegGs : 0
+0x090 SegFs : 0x3b
+0x094 SegEs : 0x23
+0x098 SegDs : 0x23
+0x09c Edi : 0x737b19a4
+0x0a0 Esi : 0x737b19a0
+0x0a4 Ebx : 0xfffffffc
+0x0a8 Edx : 4
+0x0ac Ecx : 0
+0x0b0 Eax : 0
+0x0b4 Ebp : 0x21ee20
+0x0b8 Eip : 0x77d8e13d
+0x0bc SegCs : 0x1b
+0x0c0 EFlags : 0x10213
+0x0c4 Esp : 0x21edd0
+0x0c8 SegSs : 0x23
+0x0cc ExtendedRegisters : [512] "???"

0:000> dt -r1 0x21eae8 EXCEPTION_RECORD
ntdll!EXCEPTION_RECORD
+0x000 ExceptionCode : 0xc0000005
+0x004 ExceptionFlags : 0
+0x008 ExceptionRecord : (null)
+0x00c ExceptionAddress : 0x77d8e13d
+0x010 NumberParameters : 2
+0x014 ExceptionInformation : [15] 1

0:000> !error 0xc0000005
Error code: (NTSTATUS) 0xc0000005 (3221225477) - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".


You can see the exception code is 0xc0000005 which is Access Violation
So whenever you find the KiUserExceptionDispatcher() function in call stack you can check for CONTEXT structure and EXCEPTION_RECORD structure, to find the exception code.

References:
Debugger tricks: Find all probable CONTEXT records in a crash dump

Wednesday, March 17, 2010

How to enable Windows Installer logging

How to enable Windows Installer logging Clickhere!!!