Need a PSP Debugging tool for memory leaks or least memory profiling to see if I have a leak (so I can know how much I'm actually using) . Any suggestions?
As you know here I work on DaedalusX64. I'm running into bad_alloc crashes after loading several titles in a row and after playing 1 game for extended periods. I believe the issues to be leak related that I'm looking for a tool to profile the memory usage. Also due to the nature of the app every bit of RAM I can recover can be made use of.
Need help find a tool for memory leaks
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
i'm using the memory function of the tri library written by raphael
they written to a file the allocation , the free calls with line number and name of the source so you have a trace if you free twice a memory of if you free a memory that you don't have allocated. It is not a tool but i was enough for me.
When your homebrew end the tri function written down all the memory
that you don't have freed.
link for the tri library : http://www.fx-world.org/wordpress/?cat=8
here is the tri memory library
adapt the #define amount to meet your requirements
the h file raphael use the preprocesor so you can compile your source
with the normal malloc or with the debug code
they written to a file the allocation , the free calls with line number and name of the source so you have a trace if you free twice a memory of if you free a memory that you don't have allocated. It is not a tool but i was enough for me.
When your homebrew end the tri function written down all the memory
that you don't have freed.
link for the tri library : http://www.fx-world.org/wordpress/?cat=8
here is the tri memory library
adapt the #define amount to meet your requirements
Code: Select all
Copyright (C) 2000-2006 Tomas Jakobsson.
triMemory.c
*/
#ifdef _DEBUG_MEMORY
#include <string.h>
#include <malloc.h>
#include "triTypes.h"
#include "triLog.h"
#define MAX_AMOUNT 4096
typedef struct triMemoryBlock
{
const triChar* pName;
void* pAddress;
triU32 Line;
triU32 Size;
} triMemoryBlock;
typedef struct triMemory
{
triMemoryBlock Block[MAX_AMOUNT];
triU32 PeakAlloced;
triU32 CurAlloced;
triU32 Alloced;
triU32 Freed;
triU32 Allocs;
triU32 Frees;
} triMemory;
static triMemory Memory;
/*
=============
triMemoryInit
=============
*/
triBool triMemoryInit (void)
{
memset (&Memory, 0, sizeof(triMemory));
triLogPrint ("Initializing triMemory\r\n");
return TRUE;
}
/*
=================
triMemoryShutdown
=================
*/
void triMemoryShutdown (void)
{
triU32 i;
triLogMemory ("\r\n\r\n");
triLogMemory ("Amount of allocs: %i\r\n", Memory.Allocs);
triLogMemory ("Amount of frees: %i\r\n", Memory.Frees);
triLogMemory ("Total amount of alloced memory: %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.Alloced / 1024.0f / 1024.0f, Memory.Alloced / 1024.0f, Memory.Alloced);
triLogMemory ("Total amount of freed memory: %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.Freed / 1024.0f / 1024.0f, Memory.Freed / 1024.0f, Memory.Freed);
triLogMemory ("Amount of still alloced memory: %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.CurAlloced / 1024.0f / 1024.0f, Memory.CurAlloced / 1024.0f, Memory.CurAlloced);
triLogMemory ("Peak of alloced memory: %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.PeakAlloced / 1024.0f / 1024.0f, Memory.PeakAlloced / 1024.0f, Memory.PeakAlloced);
for (i=0; i<MAX_AMOUNT; i++)
{
if (Memory.Block[i].pAddress)
{
triLogMemory ("Found alloced memory %4i at Address: %p Size: %9i File: %-24s Line: %4i\r\n", i, Memory.Block[i].pAddress, Memory.Block[i].Size,Memory.Block[i].pName, Memory.Block[i].Line);
}
}
triLogPrint ("Shutdown triMemory\r\n");
}
/*
==============
triMemoryAlloc
==============
*/
void* triMemoryAlloc (triU32 Size, const triChar* pName, const triU32 Line)
{
void* pMemory;
triU32 i;
Size = Size + 2;
pMemory = malloc (Size);
for (i=0; i<MAX_AMOUNT; i++)
{
if (Memory.Block[i].pAddress == NULL)
{
Memory.Block[i].pAddress = pMemory;
Memory.Block[i].Line = Line;
Memory.Block[i].Size = Size;
Memory.Block[i].pName = pName;
triLogMemory ("malloc %4i at Address: %p Size: %9i File: %-24s Line: %4i\r\n", i, Memory.Block[i].pAddress, Memory.Block[i].Size, Memory.Block[i].pName, Memory.Block[i].Line);
break;
}
}
Memory.CurAlloced += Memory.Block[i].Size;
Memory.Alloced += Memory.Block[i].Size;
Memory.Allocs++;
if (Memory.PeakAlloced < Memory.CurAlloced)
Memory.PeakAlloced = Memory.CurAlloced;
((triU8*)pMemory)[Size-2] = 0xDE;
((triU8*)pMemory)[Size-1] = 0xAD;
return pMemory;
}
/*
=============
triMemoryFree
=============
*/
void triMemoryFree (void* pAddress, const triChar* pName, const triU32 Line)
{
triU32 i;
for (i=0; i<MAX_AMOUNT; i++)
{
if (Memory.Block[i].pAddress && Memory.Block[i].pAddress == pAddress)
break;
}
if (i == MAX_AMOUNT)
{
triLogMemory ("Tried to delete unalloced memory at Address: %p File: %-24s Line: %4i\r\n", pAddress, pName, Line);
triLogError ("Tried to free unalloced memory\r\n");
return;
}
triLogMemory ("free %4i at Address: %p Size: %9i File: %-24s Line: %4i\r\n", i, Memory.Block[i].pAddress, Memory.Block[i].Size, pName, Line);
Memory.CurAlloced -= Memory.Block[i].Size;
Memory.Freed += Memory.Block[i].Size;
Memory.Frees++;
memset (&Memory.Block[i], 0, sizeof(triMemoryBlock));
free (pAddress);
}
/*
==============
triMemoryCheck
==============
*/
triBool triMemoryCheck (void)
{
triU32 i;
triBool Corrupt;
Corrupt = FALSE;
for (i=0; i<MAX_AMOUNT; i++)
{
if (Memory.Block[i].pAddress != NULL)
{
if (((triU8*)Memory.Block[i].pAddress)[Memory.Block[i].Size-2] != 0xDE ||
((triU8*)Memory.Block[i].pAddress)[Memory.Block[i].Size-1] != 0xAD)
{
triLogMemory ("Corruption %4i at Address: %p Size: %9i File: %-24s Line: %4i\r\n", i, Memory.Block[i].pAddress, Memory.Block[i].Size, Memory.Block[i].pName, Memory.Block[i].Line);
Corrupt = TRUE;
}
}
return Corrupt;
}
return FALSE;
}
/*
=================
triMemoryGetUsage
=================
*/
triU32 triMemoryGetUsage (void)
{
return Memory.CurAlloced;
}
#endif // _DEBUG_MEMORY
with the normal malloc or with the debug code
Code: Select all
/*
Copyright (C) 2000-2007 Tomas Jakobsson.
triMemory.h
*/
#ifndef __TRIMEMORY_H__
#define __TRIMEMORY_H__
#include <malloc.h>
#include "triTypes.h"
#ifdef _DEBUG_MEMORY
extern triBool triMemoryInit (void);
extern void triMemoryShutdown (void);
extern void* triMemoryAlloc (triU32 Size, const triChar* pName, const triU32 Line);
extern void triMemoryFree (void* pAddress, const triChar* pName, const triU32 Line);
extern triBool triMemoryCheck (void);
extern triU32 triMemoryGetUsage (void);
#define triMalloc(Size) triMemoryAlloc(Size, __FILE__, __LINE__)
#define triFree(pAddress) triMemoryFree(pAddress, __FILE__, __LINE__)
#else // _DEBUG_MEMORY
#define triMemoryInit() (void)1
#define triMemoryShutdown()
#define triMemoryCheck() (void)1
#define triMemoryGetUsage() (void)0
#define triMalloc(Size) malloc(Size)
#define triFree(pAddress) free(pAddress)
#endif // _DEBUG_MEMORY
#endif // __TRIMEMORY_H__
There probably isn't anything around that matches your needs.
First thing to try: keep a counter of mallocs/frees. Log the number of mallocs and frees every time you allocate, and at other points such as each frame rendered.
Second: keep a counter of the total memory allocated and freed, log that at the same intervals.
Finally: write your own malloc. At the start of your program, allocate all the ram you need. When you malloc, alloc space out of your own pool, give each malloc a name, like
int * space = mymalloc(spacesice, "NAMEOFALLOC");
That way you can track of who alloced what.
Jim
First thing to try: keep a counter of mallocs/frees. Log the number of mallocs and frees every time you allocate, and at other points such as each frame rendered.
Second: keep a counter of the total memory allocated and freed, log that at the same intervals.
Finally: write your own malloc. At the start of your program, allocate all the ram you need. When you malloc, alloc space out of your own pool, give each malloc a name, like
int * space = mymalloc(spacesice, "NAMEOFALLOC");
That way you can track of who alloced what.
Jim
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am