 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Kreationz
Joined: 18 May 2008 Posts: 53
|
Posted: Sat Jun 13, 2009 5:10 am Post subject: Need help find a tool for memory leaks |
|
|
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. |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Jun 14, 2009 6:30 am Post subject: |
|
|
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
| Code: | 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
|
the h file raphael use the preprocesor so you can compile your source
with the normal malloc or with the debug code
| Code: |
/*
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__
|
|
|
| Back to top |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
Posted: Sun Jun 14, 2009 9:49 pm Post subject: |
|
|
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 _________________ http://www.dbfinteractive.com |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Jun 14, 2009 11:01 pm Post subject: |
|
|
that is just the purpose of the memory functions of the tri framework.
It count a show you the linenumber source file when you perform a malloc
when you perform a free a even when you try to free a zone that has not been
allocated by you |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|