Monday, November 19, 2007

Setting an user breakpoint to debug a memory allocation

When tracking down memory leaks using the debug C-Runtime (CRT), it is often useful to set a breakpoint immediately before allocating the memory that causes the leak. By setting _crtBreakAlloc, you can cause a user-defined breakpoint at a specific point of memory allocation.

When tracking memory leaks with Debug-CRT functions, such as _CrtDumpMemoryLeaks, an allocation number enclosed in braces ({}) often appears. For example, the following is a memory leak at allocation number 18:

Detected memory leaks! Dumping objects -> {18} normal block at 0x00660BE4, 10 bytes long Data: < > CD CD CD CD CD CD CD CD CD CD Object dump complete.

It is useful to set a breakpoint right before this memory gets allocated so you can step through the callstack and see what functions are causing this memory to get allocated.We can use the Watch window and set the allocation breakpoint dynamically. This method has the advantage of not requiring any source code changes or recompiling.

To set a allocation breakpoint dynamically, perform the following steps:

1.

Start your debugging session. From the Build menu, choose Debug -> Step-Into. If you are using the "Debug Single-Threaded" or "Debug Multi- Threaded" option , follow step 1a. Otherwise, follow step 1b.

a.

Type _crtBreakAlloc in the Watch window. This shows the current allocation number at which your program will stop. This allocation number should be -1 when your program first starts.

b.

Type {,,msvcrtd.dll}*__p__crtBreakAlloc() in the Watch window. This shows the current allocation number at which your program will stop. This allocation number should be -1 when your program first starts.

2.

Double click on the -1 value, and enter the new allocation number that causes a user-defined breakpoint.

3.

From the Debug menu, choose Debug -> Go

Now the application will cause an user breakpoint just before allocating memory corresponding to the specified allocation number.

For more information about _crtBreakAlloc, please search "Tracking Heap Allocation Requests" in MSDN.

Retrieving a List of All ODBC Data Sources

The Open Database Connectivity (ODBC) API contains a function called SQLDataSources() which can be used to retrieve information about data sources which are available to an application. Below is a code snippet which fills a CStringArray with the names of all available ODBC data sources in the system.

Please include ODBC32.lib in your application before building.

   #include "sqlext.h"
 
   #define MAX_DSN_LENGTH 30
   #define MAX_DSN_DESC_LENGTH 300

HENV hEnv;

char szDSN[MAX_DSN_LENGTH];

SWORD cbDSN;

UCHAR szDescription[MAX_DSN_DESC_LENGTH];

SWORD cbDescription;

RETCODE retcode;

CStringArray * pArray= new CStringArray;

SQLAllocEnv(&hEnv);

while (retcode=SQLDataSources(hEnv, SQL_FETCH_NEXT,

(UCHAR FAR *) &szDSN, MAX_DSN_LENGTH, &cbDSN,

(UCHAR FAR *) &szDescription,MAX_DSN_DESC_LENGTH,

&cbDescription) != SQL_NO_DATA_FOUND

&&retcode!=SQL_ERROR)

{

pArray->Add( szDSN );

}

Now pArray contains the names of all the ODBC data sources available in the system.

Getting the current application path

Have u ever confronted with the need of getting the path of the current application? One method is of course to use the function GetModuleFileName(). But there is another easier method. It is figured out below:

In Win32 application, you can get to the program name through the variable __argv. You can just reference __argv directly. It is declared in stdlib.h

Test this out by adding the following simple line in your application:

   MessageBox( NULL, __argv[0], "App Path", MB_OK );