Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,117 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* glibc 验收探针,不进入运行库;插桩耗时与 RSS 不用于性能比较。
|
||||
* 只跟踪这些入口实际返回的请求字节,忽略 loader 内部产生的未知指针。
|
||||
* 固定表不调用分配器,表满直接使验收失败,不能悄悄漏记。 */
|
||||
extern void *__libc_malloc(size_t size);
|
||||
extern void *__libc_calloc(size_t count, size_t size);
|
||||
extern void *__libc_realloc(void *pointer, size_t size);
|
||||
extern void __libc_free(void *pointer);
|
||||
extern void *__libc_memalign(size_t alignment, size_t size);
|
||||
|
||||
#define CAPACITY 131072
|
||||
#define DELETED ((uintptr_t)1)
|
||||
|
||||
static struct { uintptr_t address; size_t size; } entries[CAPACITY];
|
||||
static size_t allocations, releases, allocated_bytes, released_bytes, live_bytes, peak_bytes;
|
||||
static int recording = 1;
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static size_t slot(uintptr_t address, int insert) {
|
||||
size_t first_deleted = CAPACITY;
|
||||
size_t start = (address >> 4) % CAPACITY;
|
||||
for (size_t step = 0; step < CAPACITY; step++) {
|
||||
size_t index = (start + step) % CAPACITY;
|
||||
if (entries[index].address == address) return index;
|
||||
if (entries[index].address == DELETED && first_deleted == CAPACITY) first_deleted = index;
|
||||
if (!entries[index].address) return insert && first_deleted != CAPACITY ? first_deleted : index;
|
||||
}
|
||||
if (insert && first_deleted != CAPACITY) return first_deleted;
|
||||
abort();
|
||||
}
|
||||
|
||||
static void added(void *pointer, size_t size) {
|
||||
if (!recording || !pointer) return;
|
||||
uintptr_t address = (uintptr_t)pointer;
|
||||
size_t index = slot(address, 1);
|
||||
if (entries[index].address == address) abort();
|
||||
entries[index].address = address;
|
||||
entries[index].size = size;
|
||||
allocations++;
|
||||
allocated_bytes += size;
|
||||
live_bytes += size;
|
||||
if (live_bytes > peak_bytes) peak_bytes = live_bytes;
|
||||
}
|
||||
|
||||
static void removed(uintptr_t address) {
|
||||
if (!recording || !address) return;
|
||||
size_t index = slot(address, 0);
|
||||
if (entries[index].address != address) return;
|
||||
releases++;
|
||||
released_bytes += entries[index].size;
|
||||
live_bytes -= entries[index].size;
|
||||
entries[index].address = DELETED;
|
||||
}
|
||||
|
||||
void *malloc(size_t size) {
|
||||
pthread_mutex_lock(&lock);
|
||||
void *pointer = __libc_malloc(size);
|
||||
added(pointer, size);
|
||||
pthread_mutex_unlock(&lock);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
void *calloc(size_t count, size_t size) {
|
||||
pthread_mutex_lock(&lock);
|
||||
void *pointer = __libc_calloc(count, size);
|
||||
if (pointer) added(pointer, count * size);
|
||||
pthread_mutex_unlock(&lock);
|
||||
return pointer;
|
||||
}
|
||||
|
||||
void *realloc(void *pointer, size_t size) {
|
||||
pthread_mutex_lock(&lock);
|
||||
uintptr_t address = (uintptr_t)pointer;
|
||||
void *result = __libc_realloc(pointer, size);
|
||||
/* 失败时旧块仍存活;glibc 的零大小 realloc 则释放旧块。 */
|
||||
if (result || size == 0) {
|
||||
removed(address);
|
||||
added(result, size);
|
||||
}
|
||||
pthread_mutex_unlock(&lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
int posix_memalign(void **result, size_t alignment, size_t size) {
|
||||
if (alignment < sizeof(void *) || (alignment & (alignment - 1))) return EINVAL;
|
||||
int previous_errno = errno;
|
||||
pthread_mutex_lock(&lock);
|
||||
void *pointer = __libc_memalign(alignment, size);
|
||||
if (pointer) {
|
||||
*result = pointer;
|
||||
added(pointer, size);
|
||||
}
|
||||
pthread_mutex_unlock(&lock);
|
||||
errno = previous_errno;
|
||||
return pointer ? 0 : ENOMEM;
|
||||
}
|
||||
|
||||
void free(void *pointer) {
|
||||
pthread_mutex_lock(&lock);
|
||||
removed((uintptr_t)pointer);
|
||||
__libc_free(pointer);
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
__attribute__((destructor)) static void report(void) {
|
||||
pthread_mutex_lock(&lock);
|
||||
recording = 0;
|
||||
pthread_mutex_unlock(&lock);
|
||||
fprintf(stderr, "heap_stats,%zu,%zu,%zu,%zu,%zu,%zu\n",
|
||||
allocations, releases, allocated_bytes, released_bytes, live_bytes, peak_bytes);
|
||||
}
|
||||
Reference in new issue
Block a user