[Vortex] Windows issues and memory tracking in debug builds

Yourch, Chris chris at replicus.com
Wed Nov 7 22:32:04 CET 2007


Here's a bunch of issues and suggestions related to the Windows/Visual
Studio environment:


1. The libaxl project is missing a .DEF file so it only compiles as a
static library for now.


2. Suggestion: Instead of  "vortex_frame_unref(VortexFrame * frame)" how
about "vortex_frame_unref(VortexFrame ** frame)" so that when the ref
count goes to 0 and the frame is freed you can set the frame pointer to
NULL.


3. Tracking memory allocations: For debug builds, define
_CRTDBG_MAP_ALLOC in the libvortex and libaxl Visual Studio projects
under the Properties -> C/C++ ->  preprocessor section.


4. Turning on more aggressive allocation/free checking: At line 44 of
vortex_win32.c add the following:

#ifdef _DEBUG
#include <crtdbg.h>
#endif

And, in the same module, add this to the first line of DllMain():
#ifdef _DEBUG
   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|
                    _CRTDBG_CHECK_CRT_DF|_CRTDBG_DELAY_FREE_MEM_DF|
                    _CRTDBG_LEAK_CHECK_DF);
#endif


5. Further memory tracking: To track allocations and frees for Vortex
specific objects during _DEBUG builds have axl_new() call _calloc_dbg()
and axl_free() call _free_dbg(). The debug versions of these functions
have additional parameters. They take a blocktype value (an int), the
filename and the linenumber. The blocktype is an important field. For
each specific Vortex "type" define a sub-blocktype number that is OR'ed
with the blocktype. 

// Define the memory block sub-type for Vortex types:
enum MicrosoftMemoryBlockTypes
{
	BLKTYPE_VortexChannelData = 1,  // VortexChannelData:
	BLKTYPE_char,                   // char:
	BLKTYPE_VortexChannel           // VortexChannel

	// and so on...
};

// Update the signature of axl_new():
#ifdef _DEBUG
  #define axl_new(type, count, blksubtype)  \
      (type *) _calloc_dbg(count, sizeof(type), \
                           (_CLIENT_BLOCK | ((blksubtype) << 16)), \
                           __FILE__, __LINE__)
#else
  #define axl_new(type, count)    (type *) calloc (count, sizeof (type))
#endif

// Update the signature of axl_free():
#ifdef _DEBUG
  #define axl_free(ptr, blksubtype)  \
      _free_dbg(ptr, (_CLIENT_BLOCK | ((blksubtype) << 16))
#else
  #define axl_free(ptr)    free(ptr)
#endif


Finally, when leaks are detected or the memory needs to be dumped, the
Vortex specific dump function will be called. This is defined as
follows:

#ifdef _DEBUG
void __cdecl DumpVortexObjectFunction(void *pUserData, size_t nBytes)
{
  int blktype = _CrtReportBlockType(pUserData);
  int blksubtype = ((blktype >> 16) & 0xFFFF);

  if (blksubtype == BLKTYPE_VortexChannelData)
  {
    VortexChannelData *channelData = (VortexChannelData *)pUserData;

    _RPT2(_CRT_WARN, "VortexChannelData: host=%s, channel_num = %d\n", 
               vortex_connection_get_host(channelData->connection),
               channelData->channel_num);

    _ASSERTE(channelData->connection != NULL);
  }
  else if (blksubtype == BLKTYPE_VortexChannel)
  {
    VortexChannel *channel = (VortexChannel *)pUserData;

    _RPT3(_CRT_WARN, "VortexChannel: host=%s, port=%s, channel_num =
%d\n", 
               vortex_connection_get_host(channel->connection),
               vortex_connection_get_port(channel->connection),
               channelData->channel_num);

    _ASSERTE(channel->connection != NULL);
    _ASSERTE(channel->profile != NULL);  
  }

  // And so on....

}
#endif

To install the dump function call this method as follows:
#ifdef _DEBUG
  _CrtSetDumpClient(DumpVortexObjectFunction);
#endif
This call would be placed as the 2nd line of DllMain().




Making the above changes will really help to ensure a solid Windows
version of the Vortex library.

Thanks for listening!


Best Regards,

Chris Yourch






More information about the Vortex mailing list