Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#include <stdio.h>
#include <malloc.h>
#include <errno.h>
// Set this if you want to use the sbrk definition written in this file
//#define OVERRIDE_SBRK
// Platform specific definition:
// Symbols that references the start and the end of the .heap section.
#define HEAP_SECTION_START_SYMBOL _pvHeapStart
#define HEAP_SECTION_END_SYMBOL _pvHeapLimit
extern void* HEAP_SECTION_START_SYMBOL;
extern void* HEAP_SECTION_END_SYMBOL;
void test_malloc(){
// Just display some information about the heap section
void* heap_section_start = &HEAP_SECTION_START_SYMBOL;
void* heap_section_end = &HEAP_SECTION_END_SYMBOL;
printf("Heap section start=0x%x end=0x%x size=%d\n", heap_section_start, heap_section_end, (heap_section_end - heap_section_start));
// Compute where will be the address of the next allocated memory.
// If this is the first malloc, this call wil also initialize the heap.
void* malloc_ptr = malloc(sizeof(long long int)) + sizeof(long long int);
printf("Malloc ptr=0x%x\n", malloc_ptr);
printf("Print malloc_stats:\n");
malloc_stats();
// Compute expected available memory.
// It should be the space between the next malloc pointer and the end of the heap section.
int expected_available_size = (int)(heap_section_end - malloc_ptr);
printf("Expected available size is ~%d bytes\n", expected_available_size);
// Because of the suspected issue, the actual available memory is lower.
// Instead of using the end of the heap section, malloc will use an address aligned on 4096.
// Here we compute this aligned heap end and the actual available size.
void* aligned_heap_end = (void*)(((int)heap_section_end) & ~0xFFF);
int actual_available_size = (int)(aligned_heap_end - malloc_ptr);
printf("From my understanding of the bug, the actual available size is ~%d bytes\n", actual_available_size);
printf("Let's see how much we can allocate:\n");
int size = expected_available_size;
while(size >= 0){
printf("Try to allocate %d bytes: ", size);
void* ptr = malloc(size);
if(ptr != NULL){
int wasted_memory = expected_available_size - size;
printf("allocation success, but almost %d bytes are wasted in the heap section!\n", wasted_memory);
break;
}
else
{
printf("allocation failure :-(\n");
}
size -= 32;
}
printf("Print malloc_stats:\n");
malloc_stats();
}
#ifdef OVERRIDE_SBRK
static char* heap_end = 0;
void * _sbrk_r (struct _reent *ptr, ptrdiff_t incr)
{
char *prev_heap_end;
void* heap_section_start = &HEAP_SECTION_START_SYMBOL;
void* heap_section_end = &HEAP_SECTION_END_SYMBOL;
if (heap_end == 0) {
heap_end = heap_section_start;
}
prev_heap_end = heap_end;
if (heap_end + incr > heap_section_end) {
ptr->_errno = ENOMEM;
return -1;
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
#endif // OVERRIDE_SBRK
@jerome-leroux
Copy link
Author

image1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment