Need help find a tool for memory leaks

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Kreationz
Posts: 52
Joined: Sun May 18, 2008 11:01 am

Need help find a tool for memory leaks

Post by Kreationz »

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.
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

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: 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
&#123;
	const triChar*	pName;
	void*			pAddress;
	triU32			Line;
	triU32			Size;
&#125; triMemoryBlock;

typedef struct triMemory
&#123;
	triMemoryBlock	Block&#91;MAX_AMOUNT&#93;;
	triU32			PeakAlloced;
	triU32			CurAlloced;
	triU32			Alloced;
	triU32			Freed;
	triU32			Allocs;
	triU32			Frees;
&#125; triMemory;

static triMemory Memory;

/*
=============
triMemoryInit
=============
*/
triBool triMemoryInit &#40;void&#41;
&#123;
	memset &#40;&Memory, 0, sizeof&#40;triMemory&#41;&#41;;

	triLogPrint &#40;"Initializing triMemory\r\n"&#41;;

	return TRUE;
&#125;

/*
=================
triMemoryShutdown
=================
*/
void triMemoryShutdown &#40;void&#41;
&#123;
	triU32	i;

	triLogMemory &#40;"\r\n\r\n"&#41;;
	triLogMemory &#40;"Amount of allocs&#58; %i\r\n", Memory.Allocs&#41;;
	triLogMemory &#40;"Amount of frees&#58;  %i\r\n", Memory.Frees&#41;;
	triLogMemory &#40;"Total amount of alloced memory&#58; %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.Alloced / 1024.0f / 1024.0f, Memory.Alloced / 1024.0f, Memory.Alloced&#41;;
	triLogMemory &#40;"Total amount of freed memory&#58;   %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.Freed / 1024.0f / 1024.0f, Memory.Freed / 1024.0f, Memory.Freed&#41;;
	triLogMemory &#40;"Amount of still alloced memory&#58; %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.CurAlloced / 1024.0f / 1024.0f, Memory.CurAlloced / 1024.0f, Memory.CurAlloced&#41;;
	triLogMemory &#40;"Peak of alloced memory&#58;         %7.2f MiB, %10.2f KiB, %9i B\r\n", Memory.PeakAlloced / 1024.0f / 1024.0f, Memory.PeakAlloced / 1024.0f, Memory.PeakAlloced&#41;;

	for &#40;i=0; i<MAX_AMOUNT; i++&#41;
	&#123;
		if &#40;Memory.Block&#91;i&#93;.pAddress&#41;
		&#123;
			triLogMemory &#40;"Found alloced memory %4i at Address&#58; %p Size&#58; %9i File&#58; %-24s Line&#58; %4i\r\n", i, Memory.Block&#91;i&#93;.pAddress, Memory.Block&#91;i&#93;.Size,Memory.Block&#91;i&#93;.pName, Memory.Block&#91;i&#93;.Line&#41;;
		&#125;
	&#125;

	triLogPrint &#40;"Shutdown triMemory\r\n"&#41;;
&#125;

/*
==============
triMemoryAlloc
==============
*/
void* triMemoryAlloc &#40;triU32 Size, const triChar* pName, const triU32 Line&#41;
&#123;
	void*	pMemory;
	triU32	i;

	Size	= Size + 2;
	pMemory	= malloc &#40;Size&#41;;

	for &#40;i=0; i<MAX_AMOUNT; i++&#41;
	&#123;
		if &#40;Memory.Block&#91;i&#93;.pAddress == NULL&#41;
		&#123;
			Memory.Block&#91;i&#93;.pAddress	= pMemory;
			Memory.Block&#91;i&#93;.Line		= Line;
			Memory.Block&#91;i&#93;.Size		= Size;
			Memory.Block&#91;i&#93;.pName		= pName;

			triLogMemory &#40;"malloc %4i at Address&#58; %p Size&#58; %9i File&#58; %-24s Line&#58; %4i\r\n", i, Memory.Block&#91;i&#93;.pAddress, Memory.Block&#91;i&#93;.Size, Memory.Block&#91;i&#93;.pName, Memory.Block&#91;i&#93;.Line&#41;;

			break;
		&#125;
	&#125;

	Memory.CurAlloced	+= Memory.Block&#91;i&#93;.Size;
	Memory.Alloced		+= Memory.Block&#91;i&#93;.Size;
	Memory.Allocs++;

	if &#40;Memory.PeakAlloced < Memory.CurAlloced&#41;
		Memory.PeakAlloced = Memory.CurAlloced;

	&#40;&#40;triU8*&#41;pMemory&#41;&#91;Size-2&#93;	= 0xDE;
	&#40;&#40;triU8*&#41;pMemory&#41;&#91;Size-1&#93;	= 0xAD;

	return pMemory;
&#125;

/*
=============
triMemoryFree
=============
*/
void triMemoryFree &#40;void* pAddress, const triChar* pName, const triU32 Line&#41;
&#123;
	triU32	i;

	for &#40;i=0; i<MAX_AMOUNT; i++&#41;
	&#123;
		if &#40;Memory.Block&#91;i&#93;.pAddress && Memory.Block&#91;i&#93;.pAddress == pAddress&#41;
			break;
	&#125;

	if &#40;i == MAX_AMOUNT&#41;
	&#123;
		triLogMemory &#40;"Tried to delete unalloced memory at Address&#58; %p File&#58; %-24s Line&#58; %4i\r\n", pAddress, pName, Line&#41;;

		triLogError &#40;"Tried to free unalloced memory\r\n"&#41;;

		return;
	&#125;

	triLogMemory &#40;"free   %4i at Address&#58; %p Size&#58; %9i File&#58; %-24s Line&#58; %4i\r\n", i, Memory.Block&#91;i&#93;.pAddress, Memory.Block&#91;i&#93;.Size, pName, Line&#41;;

	Memory.CurAlloced	-= Memory.Block&#91;i&#93;.Size;
	Memory.Freed		+= Memory.Block&#91;i&#93;.Size;
	Memory.Frees++;

	memset &#40;&Memory.Block&#91;i&#93;, 0, sizeof&#40;triMemoryBlock&#41;&#41;;

	free &#40;pAddress&#41;;
&#125;

/*
==============
triMemoryCheck
==============
*/
triBool triMemoryCheck &#40;void&#41;
&#123;
	triU32	i;
	triBool	Corrupt;

	Corrupt	= FALSE;

	for &#40;i=0; i<MAX_AMOUNT; i++&#41;
	&#123;
		if &#40;Memory.Block&#91;i&#93;.pAddress != NULL&#41;
		&#123;
			if &#40;&#40;&#40;triU8*&#41;Memory.Block&#91;i&#93;.pAddress&#41;&#91;Memory.Block&#91;i&#93;.Size-2&#93; != 0xDE ||
				&#40;&#40;triU8*&#41;Memory.Block&#91;i&#93;.pAddress&#41;&#91;Memory.Block&#91;i&#93;.Size-1&#93; != 0xAD&#41;
			&#123;
				triLogMemory &#40;"Corruption %4i at Address&#58; %p Size&#58; %9i File&#58; %-24s Line&#58; %4i\r\n", i, Memory.Block&#91;i&#93;.pAddress, Memory.Block&#91;i&#93;.Size, Memory.Block&#91;i&#93;.pName, Memory.Block&#91;i&#93;.Line&#41;;

				Corrupt	= TRUE;
			&#125;
		&#125;

		return Corrupt;
	&#125;

	return FALSE;
&#125;

/*
=================
triMemoryGetUsage
=================
*/
triU32 triMemoryGetUsage &#40;void&#41;
&#123;
	return Memory.CurAlloced;
&#125;

#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: Select all

/*
Copyright &#40;C&#41; 2000-2007 Tomas Jakobsson.

triMemory.h
*/

#ifndef	__TRIMEMORY_H__
#define	__TRIMEMORY_H__

#include <malloc.h>
#include "triTypes.h"

#ifdef _DEBUG_MEMORY

extern triBool	triMemoryInit		&#40;void&#41;;
extern void		triMemoryShutdown	&#40;void&#41;;
extern void*	triMemoryAlloc		&#40;triU32 Size, const triChar* pName, const triU32 Line&#41;;
extern void		triMemoryFree		&#40;void* pAddress, const triChar* pName, const triU32 Line&#41;;
extern triBool	triMemoryCheck		&#40;void&#41;;
extern triU32	triMemoryGetUsage	&#40;void&#41;;

#define triMalloc&#40;Size&#41;		triMemoryAlloc&#40;Size, __FILE__, __LINE__&#41;
#define triFree&#40;pAddress&#41;	triMemoryFree&#40;pAddress, __FILE__, __LINE__&#41;

#else // _DEBUG_MEMORY

#define triMemoryInit&#40;&#41;		&#40;void&#41;1
#define triMemoryShutdown&#40;&#41;  
#define triMemoryCheck&#40;&#41;	&#40;void&#41;1
#define triMemoryGetUsage&#40;&#41;	&#40;void&#41;0

#define triMalloc&#40;Size&#41;		malloc&#40;Size&#41;
#define triFree&#40;pAddress&#41;	free&#40;pAddress&#41;

#endif // _DEBUG_MEMORY

#endif // __TRIMEMORY_H__

User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

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
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

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
Post Reply