libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmMallocDebug.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #include "cmPrefix.h"
  4. #include "cmGlobal.h"
  5. #include "cmRpt.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. cmMmH_t _cmMdH = cmSTATIC_NULL_HANDLE;
  9. void* _cmMdAlloc(void* funcArgPtr, unsigned byteCnt)
  10. { return malloc(byteCnt); }
  11. bool _cmMdFree(void* funcArgPtr, void* ptr)
  12. { free(ptr); return true; }
  13. cmMmRC_t cmMdInitialize( unsigned guardByteCnt, unsigned alignByteCnt, unsigned flags, cmRpt_t* rptPtr )
  14. { return cmMmInitialize(&_cmMdH,_cmMdAlloc,_cmMdFree,NULL,guardByteCnt,alignByteCnt,flags,rptPtr); }
  15. cmMmRC_t cmMdFinalize()
  16. { return cmMmFinalize(&_cmMdH); }
  17. bool cmMdIsValid()
  18. { return _cmMdH.h != NULL; }
  19. unsigned cmMdGuardByteCount() { return cmMmGuardByteCount( _cmMdH); }
  20. unsigned cmMdAlignByteCount() { return cmMmAlignByteCount( _cmMdH); }
  21. unsigned cmMdInitializeFlags(){ return cmMmInitializeFlags(_cmMdH); }
  22. void* cmMdAllocate( void *orgDataPtr, unsigned eleCnt, unsigned eleByteCnt, unsigned flags)
  23. { return cmMmAllocate(_cmMdH,orgDataPtr,eleCnt,eleByteCnt,flags,NULL,NULL,0); }
  24. void* cmMdAllocateDebug( void* orgDataPtr, unsigned eleCnt, unsigned eleByteCnt, unsigned flags, const char* func, const char* fn, unsigned line)
  25. { return cmMmAllocate(_cmMdH,orgDataPtr,eleCnt,eleByteCnt,flags,fn,func,line); }
  26. void cmMdFree( void* p )
  27. { cmMmFree(_cmMdH,p); }
  28. void cmMdFreeDebug(void* p, const char* func, const char* fn, unsigned line )
  29. { cmMmFreeDebug(_cmMdH,p,fn,func,line); }
  30. void cmMdFreePtr( void* p )
  31. { cmMmFreePtr(_cmMdH,p); }
  32. void cmMdFreePtrDebug(void* p, const char* func, const char* fn, unsigned line )
  33. { cmMmFreePtrDebug(_cmMdH,p,fn,func,line); }
  34. cmChar_t* cmMdAllocStr( void* orgStrPtr, const cmChar_t* str, unsigned n, unsigned flags )
  35. {
  36. if( str==NULL)
  37. return NULL;
  38. //unsigned n = strlen(str)+1;
  39. n += 1;
  40. cmChar_t* cp = cmMdAllocate(orgStrPtr,n,sizeof(cmChar_t),flags);
  41. strncpy(cp,str,n);
  42. cp[n-1] = 0;
  43. return cp;
  44. }
  45. cmChar_t* cmMdAllocStrDebug( void* orgStrPtr, const cmChar_t* str, unsigned n, unsigned flags, const char* func, const char* fn, unsigned line )
  46. {
  47. if( str==NULL)
  48. return NULL;
  49. n += 1;
  50. cmChar_t* cp = cmMdAllocateDebug((void*)orgStrPtr,n,sizeof(cmChar_t),flags,func,fn,line);
  51. strncpy(cp,str,n);
  52. cp[n-1] = 0;
  53. return cp;
  54. }
  55. cmMmRC_t cmMdIsGuardCorrupt( unsigned id )
  56. { return cmMmIsGuardCorrupt(_cmMdH,id); }
  57. cmMmRC_t cmMdCheckAllGuards( cmRpt_t* rpt )
  58. { return cmMmCheckAllGuards(_cmMdH); }
  59. unsigned cmMdDebugId( const void* dataPtr)
  60. { return cmMmDebugId(_cmMdH,dataPtr); }
  61. cmMmRC_t cmMdReport( unsigned mmFlags )
  62. { return cmMmReport(_cmMdH,mmFlags); }
  63. //! [cmMdExample]
  64. void cmMdTest( cmRpt_t* rpt )
  65. {
  66. bool memDebugFl = true;
  67. unsigned memGuardByteCnt = memDebugFl ? 0 : 8;
  68. unsigned memAlignByteCnt = 16;
  69. unsigned memFlags = memDebugFl ? kTrackMmFl | kDeferFreeMmFl | kFillUninitMmFl | kFillFreedMmFl : 0;
  70. // initialize the library
  71. cmMdInitialize( memGuardByteCnt, memAlignByteCnt, memFlags, rpt );
  72. // Allocate a block of 16 bytes of aligned and zeroed memory.
  73. void* d0p = cmMdAllocateDebug(NULL, 1, 16, kAlignMmFl | kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ );
  74. // Allocate a block of 20 bytes of non-aligned, zeroed memory.
  75. unsigned* d1p = cmMdAllocateDebug(NULL, 1, 20, /*kAlignMmFl |*/ kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ );
  76. unsigned i;
  77. // Intentionally overwrite the guard bytes by writing
  78. // 24 bytes where only 20 where allocated
  79. for(i=0; i<3; ++i)
  80. d1p[i] = i;
  81. // Print a report showing the state of each memory block.
  82. // This should show that d1p[] has been corrupted and
  83. // memory leaks because active blocks exist.
  84. cmMdReport( 0 );
  85. // Expand d1p[] preserving the existing 20 bytes.
  86. d1p = cmMdAllocateDebug(d1p, 1, 24, kPreserveMmFl | /*kAlignMmFl |*/ kZeroMmFl, __FUNCTION__, __FILE__, __LINE__ );
  87. // Print the contents of the expanded d1p[]
  88. for(i=0; i<3; ++i)
  89. printf("%i ",d1p[i]);
  90. printf("\n");
  91. // Free d0p[] and d1p[];
  92. cmMdFreeDebug(d0p, __FUNCTION__, __FILE__, __LINE__);
  93. cmMdFreeDebug(d1p, __FUNCTION__, __FILE__, __LINE__);
  94. // Perform a write after free on d0p[].
  95. *(unsigned*)d0p = 1;
  96. // Print another report showing to test write-after-free detection.
  97. cmMdReport( 0 );
  98. // Close the library.
  99. cmMdFinalize();
  100. }
  101. //! [cmMdExample]