mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-29 18:37:41 +08:00
Add memalloc for testing memory operations.
This commit is contained in:
parent
279301f6bf
commit
ef3982d66b
@ -19,11 +19,9 @@ CFLAGS = -c -g -W \
|
|||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
#Check system:
|
#Check system:
|
||||||
SYSLIB =
|
|
||||||
CHECKSYSRES = @echo "Unknow system type!";exit 1
|
CHECKSYSRES = @echo "Unknow system type!";exit 1
|
||||||
UNIXNAME = $(shell uname -sm)
|
UNIXNAME = $(shell uname -sm)
|
||||||
UNIXTYPE = LINUX
|
shared_ldflags =
|
||||||
polarssl =
|
|
||||||
|
|
||||||
ifeq ($(CC),)
|
ifeq ($(CC),)
|
||||||
CC = g++
|
CC = g++
|
||||||
@ -42,6 +40,17 @@ ifeq ($(findstring clang++, $(CC)), clang++)
|
|||||||
-Wno-invalid-offsetof
|
-Wno-invalid-offsetof
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# For Linux
|
||||||
|
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
|
||||||
|
shared_ldflags += -lunwind -lunwind-x86_64 -lz -lpthread
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For Darwin
|
||||||
|
ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
|
||||||
|
CFLAGS += -D_XOPEN_SOURCE -Wno-deprecated-declarations
|
||||||
|
shared_ldflags += -lz -lpthread
|
||||||
|
endif
|
||||||
|
|
||||||
#Find system type.
|
#Find system type.
|
||||||
ifneq ($(SYSPATH),)
|
ifneq ($(SYSPATH),)
|
||||||
CHECKSYSRES = @echo "System is $(shell uname -sm)"
|
CHECKSYSRES = @echo "System is $(shell uname -sm)"
|
||||||
@ -53,7 +62,6 @@ LIB_PATH_DST = .
|
|||||||
DEF_PATH_DST = ./debug
|
DEF_PATH_DST = ./debug
|
||||||
|
|
||||||
CFLAGS += -I.
|
CFLAGS += -I.
|
||||||
shared_ldflags = -lunwind -lunwind-x86_64 -lz -lpthread
|
|
||||||
|
|
||||||
#Project's objs
|
#Project's objs
|
||||||
OBJS_DST = $(patsubst %.cpp, $(OBJ_PATH_DST)/%.o, $(notdir $(wildcard ./*.cpp)))
|
OBJS_DST = $(patsubst %.cpp, $(OBJ_PATH_DST)/%.o, $(notdir $(wildcard ./*.cpp)))
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <ucontext.h>
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
|
#include "libmm.h"
|
||||||
|
|
||||||
static void stacktrace(void)
|
static void stacktrace(void)
|
||||||
{
|
{
|
||||||
@ -35,8 +37,6 @@ static void stacktrace(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void *(*malloc_fn)(size_t);
|
|
||||||
static malloc_fn __malloc_fn = NULL;
|
|
||||||
static size_t total_size = 0;
|
static size_t total_size = 0;
|
||||||
static bool __check = false;
|
static bool __check = false;
|
||||||
static pthread_mutex_t __lock;
|
static pthread_mutex_t __lock;
|
||||||
@ -45,7 +45,6 @@ static pthread_once_t once_control = PTHREAD_ONCE_INIT;
|
|||||||
|
|
||||||
static void once_init(void)
|
static void once_init(void)
|
||||||
{
|
{
|
||||||
__malloc_fn = (malloc_fn) dlsym(RTLD_NEXT, "malloc");
|
|
||||||
pthread_mutex_init(&__lock, NULL);
|
pthread_mutex_init(&__lock, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ void *malloc(size_t size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = __malloc_fn(size);
|
ptr = mymalloc(size);
|
||||||
if (ptr && __check) {
|
if (ptr && __check) {
|
||||||
if (size == 8208) {
|
if (size == 8208) {
|
||||||
//abort();
|
//abort();
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void *mymalloc(size_t size);
|
||||||
|
void print_mem_list();
|
||||||
|
|
||||||
//void start_check(void);
|
//void start_check(void);
|
||||||
//void stop_check(void);
|
//void stop_check(void);
|
||||||
|
|
||||||
|
169
test/libmm/memalloc.cpp
Normal file
169
test/libmm/memalloc.cpp
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
// Copy from https://github.com/arjun024/memalloc
|
||||||
|
/* Only for the debug printf */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "libmm.h"
|
||||||
|
|
||||||
|
typedef char ALIGN[16];
|
||||||
|
|
||||||
|
union header {
|
||||||
|
struct {
|
||||||
|
size_t size;
|
||||||
|
unsigned is_free;
|
||||||
|
union header *next;
|
||||||
|
} s;
|
||||||
|
/* force the header to be aligned to 16 bytes */
|
||||||
|
ALIGN stub;
|
||||||
|
};
|
||||||
|
typedef union header header_t;
|
||||||
|
|
||||||
|
header_t *head = NULL, *tail = NULL;
|
||||||
|
pthread_mutex_t global_malloc_lock;
|
||||||
|
|
||||||
|
static header_t *get_free_block(size_t size)
|
||||||
|
{
|
||||||
|
header_t *curr = head;
|
||||||
|
while(curr) {
|
||||||
|
/* see if there's a free block that can accomodate requested size */
|
||||||
|
if (curr->s.is_free && curr->s.size >= size)
|
||||||
|
return curr;
|
||||||
|
curr = curr->s.next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void *block)
|
||||||
|
{
|
||||||
|
header_t *header, *tmp;
|
||||||
|
/* program break is the end of the process's data segment */
|
||||||
|
void *programbreak;
|
||||||
|
|
||||||
|
if (!block)
|
||||||
|
return;
|
||||||
|
pthread_mutex_lock(&global_malloc_lock);
|
||||||
|
header = (header_t*)block - 1;
|
||||||
|
/* sbrk(0) gives the current program break address */
|
||||||
|
programbreak = sbrk(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if the block to be freed is the last one in the
|
||||||
|
linked list. If it is, then we could shrink the size of the
|
||||||
|
heap and release memory to OS. Else, we will keep the block
|
||||||
|
but mark it as free.
|
||||||
|
*/
|
||||||
|
if ((char*)block + header->s.size == programbreak) {
|
||||||
|
if (head == tail) {
|
||||||
|
head = tail = NULL;
|
||||||
|
} else {
|
||||||
|
tmp = head;
|
||||||
|
while (tmp) {
|
||||||
|
if(tmp->s.next == tail) {
|
||||||
|
tmp->s.next = NULL;
|
||||||
|
tail = tmp;
|
||||||
|
}
|
||||||
|
tmp = tmp->s.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
sbrk() with a negative argument decrements the program break.
|
||||||
|
So memory is released by the program to OS.
|
||||||
|
*/
|
||||||
|
sbrk(0 - header->s.size - sizeof(header_t));
|
||||||
|
/* Note: This lock does not really assure thread
|
||||||
|
safety, because sbrk() itself is not really
|
||||||
|
thread safe. Suppose there occurs a foregin sbrk(N)
|
||||||
|
after we find the program break and before we decrement
|
||||||
|
it, then we end up realeasing the memory obtained by
|
||||||
|
the foreign sbrk().
|
||||||
|
*/
|
||||||
|
pthread_mutex_unlock(&global_malloc_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
header->s.is_free = 1;
|
||||||
|
pthread_mutex_unlock(&global_malloc_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *mymalloc(size_t size)
|
||||||
|
{
|
||||||
|
size_t total_size;
|
||||||
|
void *block;
|
||||||
|
header_t *header;
|
||||||
|
if (!size)
|
||||||
|
return NULL;
|
||||||
|
pthread_mutex_lock(&global_malloc_lock);
|
||||||
|
header = get_free_block(size);
|
||||||
|
if (header) {
|
||||||
|
/* Woah, found a free block to accomodate requested memory. */
|
||||||
|
header->s.is_free = 0;
|
||||||
|
pthread_mutex_unlock(&global_malloc_lock);
|
||||||
|
return (void*)(header + 1);
|
||||||
|
}
|
||||||
|
/* We need to get memory to fit in the requested block and header from OS. */
|
||||||
|
total_size = sizeof(header_t) + size;
|
||||||
|
block = sbrk(total_size);
|
||||||
|
if (block == (void*) -1) {
|
||||||
|
pthread_mutex_unlock(&global_malloc_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
header = (header_t*) block;
|
||||||
|
header->s.size = size;
|
||||||
|
header->s.is_free = 0;
|
||||||
|
header->s.next = NULL;
|
||||||
|
if (!head)
|
||||||
|
head = header;
|
||||||
|
if (tail)
|
||||||
|
tail->s.next = header;
|
||||||
|
tail = header;
|
||||||
|
pthread_mutex_unlock(&global_malloc_lock);
|
||||||
|
return (void*)(header + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *calloc(size_t num, size_t nsize)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
void *block;
|
||||||
|
if (!num || !nsize)
|
||||||
|
return NULL;
|
||||||
|
size = num * nsize;
|
||||||
|
/* check mul overflow */
|
||||||
|
if (nsize != size / num)
|
||||||
|
return NULL;
|
||||||
|
block = mymalloc(size);
|
||||||
|
if (!block)
|
||||||
|
return NULL;
|
||||||
|
memset(block, 0, size);
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *realloc(void *block, size_t size)
|
||||||
|
{
|
||||||
|
header_t *header;
|
||||||
|
void *ret;
|
||||||
|
if (!block || !size)
|
||||||
|
return mymalloc(size);
|
||||||
|
header = (header_t*)block - 1;
|
||||||
|
if (header->s.size >= size)
|
||||||
|
return block;
|
||||||
|
ret = mymalloc(size);
|
||||||
|
if (ret) {
|
||||||
|
/* Relocate contents to the new bigger block */
|
||||||
|
memcpy(ret, block, header->s.size);
|
||||||
|
/* Free the old memory block */
|
||||||
|
free(block);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A debug function to print the entire link list */
|
||||||
|
void print_mem_list()
|
||||||
|
{
|
||||||
|
header_t *curr = head;
|
||||||
|
printf("head = %p, tail = %p \n", (void*)head, (void*)tail);
|
||||||
|
while(curr) {
|
||||||
|
printf("addr = %p, size = %zu, is_free=%u, next=%p\n",
|
||||||
|
(void*)curr, curr->s.size, curr->s.is_free, (void*)curr->s.next);
|
||||||
|
curr = curr->s.next;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user