Added an optional memory tracker (disabled by default) for detecting memory leaks and tracking allocations in the library.
This commit is contained in:
parent
d5c5846d71
commit
849ba95609
|
@ -0,0 +1,70 @@
|
|||
#ifndef CMEMORYTRACKER_H_INCLUDED
|
||||
#define CMEMORYTRACKER_H_INCLUDED
|
||||
|
||||
#include "../include/cAudioDefines.h"
|
||||
|
||||
#ifdef CAUDIO_USE_MEMORYTRACKER
|
||||
|
||||
#include <map>
|
||||
#include "../Headers/cMutex.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
class cMemoryTracker
|
||||
{
|
||||
public:
|
||||
cMemoryTracker();
|
||||
~cMemoryTracker();
|
||||
|
||||
static cMemoryTracker* Instance()
|
||||
{
|
||||
static cMemoryTracker Singleton;
|
||||
return &Singleton;
|
||||
}
|
||||
|
||||
void AddAllocation(void* pointer, size_t size, const char* filename, int line, const char* function);
|
||||
void RemoveAllocation(void* pointer);
|
||||
|
||||
private:
|
||||
cAudioMutex Mutex;
|
||||
|
||||
struct cTrackedMemoryBlock
|
||||
{
|
||||
size_t size;
|
||||
const char* filename;
|
||||
int line;
|
||||
const char* function;
|
||||
};
|
||||
|
||||
std::map<void*, cTrackedMemoryBlock> TrackedBlocks;
|
||||
|
||||
#ifdef CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
struct Statistics
|
||||
{
|
||||
Statistics() : AllocationHighWaterMark(0), CurrentAllocationBytes(0),
|
||||
TotalAllocationBytes(0), MaxNumAllocations(0),
|
||||
CurrentNumAllocations(0), TotalNumAllocations(0)
|
||||
{ }
|
||||
size_t AllocationHighWaterMark;
|
||||
size_t CurrentAllocationBytes;
|
||||
size_t TotalAllocationBytes;
|
||||
|
||||
size_t MaxNumAllocations;
|
||||
size_t CurrentNumAllocations;
|
||||
size_t TotalNumAllocations;
|
||||
} MemStats;
|
||||
#endif
|
||||
|
||||
void DumpLeaks();
|
||||
|
||||
#ifdef CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
std::ofstream outMemLog;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif //! CMEMORYTRACKER_H_INCLUDED
|
|
@ -0,0 +1,116 @@
|
|||
#include "../Headers/cMemoryTracker.h"
|
||||
|
||||
#ifdef CAUDIO_USE_MEMORYTRACKER
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
|
||||
cMemoryTracker::cMemoryTracker()
|
||||
{
|
||||
#ifdef CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
outMemLog.open("cAudioMemoryLog.log");
|
||||
#endif
|
||||
}
|
||||
|
||||
cMemoryTracker::~cMemoryTracker()
|
||||
{
|
||||
#ifdef CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
outMemLog.close();
|
||||
#endif
|
||||
DumpLeaks();
|
||||
}
|
||||
|
||||
void cMemoryTracker::AddAllocation(void* pointer, size_t size, const char* filename, int line, const char* function)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
cTrackedMemoryBlock block;
|
||||
block.size = size;
|
||||
block.filename = filename;
|
||||
block.line = line;
|
||||
block.function = function;
|
||||
TrackedBlocks[pointer] = block;
|
||||
|
||||
#ifdef CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
MemStats.CurrentAllocationBytes += size;
|
||||
MemStats.TotalAllocationBytes += size;
|
||||
|
||||
MemStats.CurrentNumAllocations += 1;
|
||||
MemStats.TotalNumAllocations += 1;
|
||||
|
||||
MemStats.AllocationHighWaterMark = MemStats.CurrentAllocationBytes > MemStats.AllocationHighWaterMark ? MemStats.CurrentAllocationBytes : MemStats.AllocationHighWaterMark;
|
||||
MemStats.MaxNumAllocations = MemStats.CurrentNumAllocations > MemStats.MaxNumAllocations ? MemStats.CurrentNumAllocations : MemStats.MaxNumAllocations;
|
||||
#endif
|
||||
|
||||
#ifdef CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
if(outMemLog.good())
|
||||
{
|
||||
outMemLog << "Allocation at " << pointer << " with size " << size << " bytes in " << filename << " (Line: " << line << ") function: " << function << std::endl;
|
||||
outMemLog.flush();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void cMemoryTracker::RemoveAllocation(void* pointer)
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
std::map<void*, cTrackedMemoryBlock>::iterator it = TrackedBlocks.find(pointer);
|
||||
if(it != TrackedBlocks.end())
|
||||
{
|
||||
#ifdef CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
if(outMemLog.good())
|
||||
{
|
||||
outMemLog << "Deallocation of address " << pointer << " with size " << it->second.size << " bytes in " << it->second.filename << " (Line: " << it->second.line << ") function: " << it->second.function << std::endl;
|
||||
outMemLog.flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
size_t size = it->second.size;
|
||||
MemStats.CurrentAllocationBytes -= size;
|
||||
MemStats.CurrentNumAllocations -= 1;
|
||||
#endif
|
||||
TrackedBlocks.erase(pointer);
|
||||
}
|
||||
}
|
||||
|
||||
void cMemoryTracker::DumpLeaks()
|
||||
{
|
||||
cAudioMutexBasicLock lock(Mutex);
|
||||
|
||||
std::ofstream leakFile("cAudioMemoryLeaks.log");
|
||||
|
||||
#ifdef CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
//Dump Statistics
|
||||
leakFile << "Highest Amount of Allocated Memory: " << MemStats.AllocationHighWaterMark << " bytes." << std::endl;
|
||||
leakFile << "Memory Allocated at Shutdown: " << MemStats.CurrentAllocationBytes << " bytes." << std::endl;
|
||||
leakFile << "Total Allocated Memory: " << MemStats.TotalAllocationBytes << " bytes." << std::endl;
|
||||
|
||||
leakFile << "Highest Number of Allocated Objects: " << MemStats.MaxNumAllocations << std::endl;
|
||||
leakFile << "Objects Allocated at Shutdown: " << MemStats.CurrentNumAllocations << std::endl;
|
||||
leakFile << "Total Objects Allocated: " << MemStats.TotalNumAllocations << std::endl;
|
||||
leakFile << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<void*, cTrackedMemoryBlock>::iterator it;
|
||||
for(it = TrackedBlocks.begin(); it != TrackedBlocks.end(); it++)
|
||||
{
|
||||
if(leakFile.good())
|
||||
{
|
||||
leakFile << "Address:" << it->first << " Size:" << it->second.size << " in " << it->second.filename << " (Line: " << it->second.line << ") function: " << it->second.function << std::endl;
|
||||
leakFile.flush();
|
||||
}
|
||||
}
|
||||
|
||||
if(TrackedBlocks.size() == 0)
|
||||
{
|
||||
leakFile << "No Leaks Detected!" << std::endl;
|
||||
leakFile.flush();
|
||||
}
|
||||
|
||||
leakFile.close();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,18 +1,34 @@
|
|||
#include "../Headers/cStandardMemoryProvider.h"
|
||||
#include "../Headers/cMemoryTracker.h"
|
||||
#include <stdlib.h>
|
||||
#include <limits>
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace cAudio
|
||||
{
|
||||
void* cStandardMemoryProvider::Allocate(size_t size, const char* filename, int line, const char* function)
|
||||
{
|
||||
return malloc(size);
|
||||
void* ptr = malloc(size);
|
||||
#ifdef CAUDIO_USE_MEMORYTRACKER
|
||||
cMemoryTracker::Instance()->AddAllocation(ptr, size, filename, line, function);
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void cStandardMemoryProvider::Free(void* pointer)
|
||||
{
|
||||
if(pointer)
|
||||
{
|
||||
#ifdef CAUDIO_USE_MEMORYTRACKER
|
||||
cMemoryTracker::Instance()->RemoveAllocation(pointer);
|
||||
#endif
|
||||
free(pointer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,6 +240,10 @@
|
|||
RelativePath=".\Headers\cMemorySource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cMemoryTracker.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Headers\cMutex.h"
|
||||
>
|
||||
|
@ -352,6 +356,10 @@
|
|||
RelativePath=".\Source\cMemorySource.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cMemoryTracker.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\cMutex.cpp"
|
||||
>
|
||||
|
|
|
@ -65,6 +65,15 @@
|
|||
//! Tells cAudio to use the C standard memory functions for allocations (memalloc and free)
|
||||
#define CAUDIO_MEMORY_USE_STD
|
||||
|
||||
//! Activates the internal memory tracker, which can be used to detect and locate memory leaks.
|
||||
//#define CAUDIO_USE_MEMORYTRACKER
|
||||
|
||||
//! Tells the memory tracker to generate statistics on memory usage by cAudio
|
||||
//#define CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
|
||||
//! Tells the memory tracker to log each and every allocation done by cAudio. This can be very slow, use only if you are debugging an issue.
|
||||
//#define CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
|
||||
#endif //CAUDIO_PLATFORM_WIN
|
||||
|
||||
///////////////////////
|
||||
|
@ -112,6 +121,15 @@
|
|||
//! Tells cAudio to use the C standard memory functions for allocations (memalloc and free)
|
||||
#define CAUDIO_MEMORY_USE_STD
|
||||
|
||||
//! Activates the internal memory tracker, which can be used to detect and locate memory leaks.
|
||||
//#define CAUDIO_USE_MEMORYTRACKER
|
||||
|
||||
//! Tells the memory tracker to generate statistics on memory usage by cAudio
|
||||
//#define CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
|
||||
//! Tells the memory tracker to log each and every allocation done by cAudio. This can be very slow, use only if you are debugging an issue.
|
||||
//#define CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
|
||||
#endif //CAUDIO_PLATFORM_MAC
|
||||
|
||||
/////////////////////
|
||||
|
@ -148,6 +166,15 @@
|
|||
//! Tells cAudio to use the C standard memory functions for allocations (memalloc and free)
|
||||
#define CAUDIO_MEMORY_USE_STD
|
||||
|
||||
//! Activates the internal memory tracker, which can be used to detect and locate memory leaks.
|
||||
//#define CAUDIO_USE_MEMORYTRACKER
|
||||
|
||||
//! Tells the memory tracker to generate statistics on memory usage by cAudio
|
||||
//#define CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
|
||||
//! Tells the memory tracker to log each and every allocation done by cAudio. This can be very slow, use only if you are debugging an issue.
|
||||
//#define CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
|
||||
#endif //CAUDIO_PLATFORM_IPHONE
|
||||
|
||||
////////////////////
|
||||
|
@ -198,6 +225,15 @@
|
|||
//! Tells cAudio to use the C standard memory functions for allocations (memalloc and free)
|
||||
#define CAUDIO_MEMORY_USE_STD
|
||||
|
||||
//! Activates the internal memory tracker, which can be used to detect and locate memory leaks.
|
||||
//#define CAUDIO_USE_MEMORYTRACKER
|
||||
|
||||
//! Tells the memory tracker to generate statistics on memory usage by cAudio
|
||||
//#define CAUDIO_MEMORYTRACKER_GENERATE_STATISTICS
|
||||
|
||||
//! Tells the memory tracker to log each and every allocation done by cAudio. This can be very slow, use only if you are debugging an issue.
|
||||
//#define CAUDIO_MEMORYTRACKER_LOG_ALL_ALLOCATIONS
|
||||
|
||||
#endif //CAUDIO_PLATFORM_LINUX
|
||||
|
||||
#endif //CAUDIODEFINES_H
|
||||
|
|
Loading…
Reference in New Issue