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:
parent
927a7bdb4b
commit
8ff4f1aec9
3 changed files with 94 additions and 3 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue