Add optional (define BUFFER_ALLOC_DEBUG to enable it) code to check for code overflowing buffer_alloc()-allocated buffers.

Also add a panicf() if buffer_alloc() doesn't have enough space left to allocate a requested buffer


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28173 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Frank Gevaerts 2010-09-26 12:05:42 +00:00
parent 927a7bdb4b
commit 8ff4f1aec9
3 changed files with 94 additions and 3 deletions

View file

@ -20,6 +20,8 @@
****************************************************************************/
#include <stdio.h>
#include "buffer.h"
#include "panic.h"
#include "logf.h"
#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
unsigned char audiobuffer[(MEM*1024-256)*1024];
@ -31,20 +33,94 @@ extern unsigned char audiobuffer[];
unsigned char *audiobuf;
#ifdef BUFFER_ALLOC_DEBUG
static unsigned char *audiobuf_orig_start;
struct buffer_start_marker
{
unsigned int magic;
size_t buffer_size;
};
#define BUF_MAGIC 0xDEADD0D0
struct buffer_end_marker
{
unsigned int magic;
int last;
};
#endif /* BUFFER_ALLOC_DEBUG */
void buffer_init(void)
{
/* 32-bit aligned */
audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3);
#ifdef BUFFER_ALLOC_DEBUG
audiobuf_orig_start = audiobuf;
#endif /* BUFFER_ALLOC_DEBUG */
}
void *buffer_alloc(size_t size)
{
void *retval = audiobuf;
audiobuf += size;
#ifdef BUFFER_ALLOC_DEBUG
struct buffer_start_marker *start;
struct buffer_end_marker *end;
#endif /* BUFFER_ALLOC_DEBUG */
/* 32-bit aligned */
audiobuf = (void *)(((unsigned long)audiobuf + 3) & ~3);
size = (size + 3) & ~3;
#ifdef BUFFER_ALLOC_DEBUG
retval +=sizeof(struct buffer_start_marker);
end=(struct buffer_end_marker*)(audiobuf - sizeof(struct buffer_end_marker));
if(end->magic == BUF_MAGIC)
{
end->last=0;
}
start=(struct buffer_start_marker*)audiobuf;
start->magic = BUF_MAGIC;
start->buffer_size = size;
end=(struct buffer_end_marker*)(audiobuf+sizeof(struct buffer_start_marker)+size);
end->magic = BUF_MAGIC;
end->last = 1;
audiobuf = ((unsigned char *)end) + sizeof(struct buffer_end_marker);
logf("Alloc %x %d",(unsigned int)retval,size);
#else /* !BUFFER_ALLOC_DEBUG */
audiobuf += size;
#endif /* BUFFER_ALLOC_DEBUG */
if (audiobuf > audiobufend) {
panicf("OOM: %d bytes", (int) size);
}
return retval;
}
#ifdef BUFFER_ALLOC_DEBUG
void buffer_alloc_check(char *name)
{
unsigned char *buf_ptr = audiobuf_orig_start;
struct buffer_start_marker *start;
struct buffer_end_marker *end;
while(buf_ptr < audiobuf)
{
start=(struct buffer_start_marker*)buf_ptr;
if(start->magic != BUF_MAGIC)
{
panicf("%s corrupted buffer %x start", name,(unsigned int)buf_ptr+sizeof(struct buffer_start_marker));
}
end=(struct buffer_end_marker*)(buf_ptr+sizeof(struct buffer_start_marker)+start->buffer_size);
if(end->magic != BUF_MAGIC)
{
panicf("%s corrupted %x end", name,(unsigned int)buf_ptr+sizeof(struct buffer_start_marker));
}
if(end->last)
break;
buf_ptr=((unsigned char *)end)+sizeof(struct buffer_end_marker);
}
}
#endif /* BUFFER_ALLOC_DEBUG */

View file

@ -39,4 +39,8 @@ extern unsigned char *audiobuf;
void buffer_init(void) INIT_ATTR;
void *buffer_alloc(size_t size);
#ifdef BUFFER_ALLOC_DEBUG
void buffer_alloc_check(char *name);
#endif
#endif

View file

@ -27,6 +27,7 @@
#include "kernel.h"
#include "cpu.h"
#include "string.h"
#include "buffer.h"
#ifdef RB_PROFILE
#include <profile.h>
#endif
@ -1160,6 +1161,16 @@ void switch_thread(void)
if (UNLIKELY(thread->stack[0] != DEADBEEF) && thread->stack_size > 0)
thread_stkov(thread);
#ifdef BUFFER_ALLOC_DEBUG
/* Check if the current thread just did bad things with buffer_alloc()ed
* memory */
{
static char name[32];
thread_get_name(name, 32, thread);
buffer_alloc_check(name);
}
#endif
#if NUM_CORES > 1
/* Run any blocking operations requested before switching/sleeping */
run_blocking_ops(core, thread);