?
Solved

how to debug crash in malloc ?

Posted on 2005-03-16
13
Medium Priority
?
607 Views
Last Modified: 2008-01-09
Hi ,

I am using Miscrosoft dev studio ver 6.0. I am getting a crash in malloc after running a program. It is giving a pop up error of "unhandled memory exception". How should I debug that?
Could this be due to less heap available? I increased the heap size from default value of 1 MB to 2MB using linker option /heap: 2MB, still it doesn't help.

Is there any tool available in dev studio which can help me in debugging this problem?

Thanks in advance.

avimal
0
Comment
Question by:avimal
  • 3
  • 2
  • 2
  • +3
10 Comments
 
LVL 16

Accepted Solution

by:
PaulCaswell earned 336 total points
ID: 13555379
Use the _Crt... functions. They allow you to hook into all memory allocation and check the validity of the heap at almost any time.

Paul

Here's some code I use but I cant remember how I use it. I'll be back on Monday if you havent fixed it by then.

...
// Log the memory state.
void LogMemory ( int ref, int line );
#define MEM(ref) TESTING(LogMemory(ref,__LINE__))
void DbgMemStart ( void ); // Call this at startup.
...
// Log the memory state.
void LogMemory ( int ref, int line )
{
      static _CrtMemState states[100];
      static bool stateUsed[lengthof(states)] = {false,};

      if ( stateUsed [ref] )
      {
            _CrtMemState now, diff;
            _CrtMemCheckpoint(&now);
            if ( _CrtMemDifference( &diff, &states[ref], &now ) )
            {
                  // Different! Dump it!
                  _CrtMemDumpStatistics ( &diff );
                  stateUsed [ref] = false;
            }
      }
      else
      {
            _CrtMemCheckpoint(&states[ref]);
            stateUsed[ref] = true;
      }
      
      MEMORYSTATUS state;
      
      state.dwLength = sizeof (state);
      
      GlobalMemoryStatus (&state);
      AddToMessageLog( 0, "MEM,%d,%d,%ld,%ld,%ld", ref, line,
            state.dwAvailPhys, state.dwAvailPageFile, state.dwAvailVirtual );
}

/* ALLOCATION HOOK FUNCTION
   -------------------------
   An allocation hook function can have many, many different
   uses. This one simply logs each allocation operation in a file.
*/
#define  nNoMansLandSize   4

typedef struct _CrtMemBlockHeader
{
// Pointer to the block allocated just before this one:
   struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
   struct _CrtMemBlockHeader *pBlockHeaderPrev;
   char *szFileName;    // File name
   int nLine;           // Line number
   size_t nDataSize;    // Size of user block
   int nBlockUse;       // Type of block
   long lRequest;       // Allocation number
// Buffer just before (lower than) the user's memory:
   unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;

/* In an actual memory block in the debug heap,
 * this structure is followed by:
 *   unsigned char data[nDataSize];
 *   unsigned char anotherGap[nNoMansLandSize];
 */

int __cdecl MyAllocHook(
   int      nAllocType,
   void   * pvData,
   size_t   nSize,
   int      nBlockUse,
   long     lRequest,
   const unsigned char * szFileName,
   int      nLine
   )
{
#if 1
      char *operation[] = { "", "+", "+-", "-" };
      char *blockType[] = { "F", "N", "C", "I", "C" };
      
      //if ( nBlockUse != _CRT_BLOCK ) // Ignore internal C runtime library allocations
//      if ( !InMsgLog )
      {
            int size = nSize;
            long id = lRequest;

            if ( pvData != NULL )
            {
                  _CrtMemBlockHeader * h = (_CrtMemBlockHeader *) ((char*)pvData - sizeof(_CrtMemBlockHeader));
                  size = h->nDataSize;
                  id = h->lRequest;
            }
            //AddToMessageLog ( 0, "MEMOP,%s%d,%s,%ld,%ld,%d", operation[nAllocType], size, blockType[nBlockUse], id, GetCurrentThreadId(), Line );
      }
#endif
      return( TRUE );         // Allow the memory operation to proceed
}

/* CLIENT DUMP HOOK FUNCTION
   -------------------------
   A hook function for dumping a Client block usually reports some
   or all of the contents of the block in question.  The function
   below also checks the data in several ways, and reports corruption
   or inconsistency as an assertion failure.
*/
void __cdecl MyDumpClientHook(
   void * pUserData,
   size_t nBytes
   )
{
      AddToMessageLog ( 0, "MEMDMP,%d", nBytes );
}

/* REPORT HOOK FUNCTION
   --------------------
   Again, report hook functions can serve a very wide variety of purposes.
   This one logs error and assertion failure debug reports in the
   log file, along with 'Damage' reports about overwritten memory.

   By setting the retVal parameter to zero, we are instructing _CrtDbgReport
   to return zero, which causes execution to continue. If we want the function
   to start the debugger, we should have _CrtDbgReport return one.
*/
int MyReportHook(
   int   nRptType,
   char *szMsg,
   int  *retVal
   )
{
   char *RptTypes[] = { "W", "E", "A" };
/*
   if ( ( nRptType > 0 ) || ( strstr( szMsg, "DAMAGE" ) ) )
      fprintf( logFile, "%s: %s", RptTypes[nRptType], szMsg );
*/
   if ( ( nRptType > 0 ) || ( strstr( szMsg, "DAMAGE" ) ) )
         AddToMessageLog ( 0, "MEMRPT,%s,%s", RptTypes[nRptType], szMsg );
   *retVal = 0;

   return( TRUE );         // Allow the report to be made as usual
   
}

void DbgMemStart ( void )
{
      // Install the hook functions
      _CrtSetDumpClient( MyDumpClientHook );
      _CrtSetAllocHook( MyAllocHook );
      _CrtSetReportHook( MyReportHook );
      
      _CrtSetDbgFlag(_CrtSetDbgFlag(0) | _CRTDBG_CHECK_CRT_DF);
}

0
 
LVL 30

Assisted Solution

by:Axter
Axter earned 332 total points
ID: 13555605
Hi avimal,

Run your program in Debug mode.  When it crashes, check out your stack, by pressing (ALT-7).
Look down your stack untill you see a layer that points to your code.

David Maisonave :-)
Cheers!
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 13556166
Avimal,

Axters idea may work but usually memory corruption happens some time before the crash. If you take the time to install the above code it would help you find exactly where the fault is happening. By all means use Axtrers idea first! It's quick and may give you a good idea about what's going on.

Paul
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 22

Assisted Solution

by:grg99
grg99 earned 332 total points
ID: 13556917
As a quick kludge you could try calling this function instead of malloc.  It pads each block up in size.  This helps detect overrunning blocks.


void * mymalloc( int size ) { int Stretch = 50;  void * p;
   p = (void *)   ( (int) malloc( size + 2 * Stretch ) + Stretch );
  return( p );
}
0
 
LVL 30

Expert Comment

by:Axter
ID: 13557169
>>As a quick kludge you could try calling this function instead of malloc.  It pads each block up in size.  This helps detect
>>overrunning blocks.

That's a great idea.  I might have to steel that, and add it to my debug code.

http://code.axter.com/debuglog.h 
http://code.axter.com/debuglog.c

http://code.axter.com/debugalloc.h 
http://code.axter.com/debugalloc.cpp

0
 
LVL 22

Expert Comment

by:grg99
ID: 13557546
I've been slow to  patent this tremendous snippet of code, so I guess you can steal it.  :)

0
 
LVL 1

Expert Comment

by:ccwork
ID: 13580525
I have to point out that 99% are (your) program bug, not malloc bug.
0
 
LVL 12

Expert Comment

by:stefan73
ID: 13596238
Hi ccwork,
> I have to point out that 99% are (your) program bug, not malloc bug.

99.99% ;-)

In case you're totally desparate, ask someone else to review your code. That's usually better than chasing phantom bugs in malloc.

Everybody uses malloc, zillions of times per second. Believe me, there's no bug in malloc.

Cheers!

Stefan
0
 

Expert Comment

by:Vikram_B
ID: 13725613
Hi grg99,

> As a quick kludge you could try calling this function instead of malloc.

although i didnt initiate this question, i needed some guidance.

it's not clear to me how the code can help.

as i understand, u r allocating required size + 100bytes and then returning the pointer starting from 50th location. i guess i missed some point here. could u help??
0
 
LVL 22

Expert Comment

by:grg99
ID: 13725791
Okay, what the function does is add a little padding before and after each block.

If your program crashes in malloc() before you add this function, and doesnt crash AFTER you add it, then it's clear the problem is somewhere you're writing past the end (or before the begining) of some malloced block.  Then it's just  a small matter of figuring out which block, and why.

0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
Suggested Courses

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question