Signed-off-by: GodKingBS <283805320@qq.com>
main
GodKingBS 2 months ago
parent 31b9bf56f4
commit 20580d5a1c

@ -36,8 +36,7 @@
#include "types.h"
#include "debug.h"
/* User-facing macro to sprintf() to a dynamically allocated buffer. */
/* 提供给用户使用的宏用于将sprintf()的输出到一个动态分配的缓冲区。 */
#define alloc_printf(_str...) ({ \
u8* _tmp; \
s32 _len = snprintf(NULL, 0, _str); \
@ -47,29 +46,24 @@
_tmp; \
})
/* Macro to enforce allocation limits as a last-resort defense against
integer overflows. */
/* 宏,用于强制执行分配限制,作为防止整数溢出的最后一道防线。 */
#define ALLOC_CHECK_SIZE(_s) do { \
if ((_s) > MAX_ALLOC) \
ABORT("Bad alloc request: %u bytes", (_s)); \
} while (0)
/* Macro to check malloc() failures and the like. */
/* 宏用于检查malloc()失败等情况。 */
#define ALLOC_CHECK_RESULT(_r, _s) do { \
if (!(_r)) \
ABORT("Out of memory: can't allocate %u bytes", (_s)); \
} while (0)
/* Magic tokens used to mark used / freed chunks. */
#define ALLOC_MAGIC_C1 0xFF00FF00 /* Used head (dword) */
#define ALLOC_MAGIC_F 0xFE00FE00 /* Freed head (dword) */
#define ALLOC_MAGIC_C2 0xF0 /* Used tail (byte) */
/* Positions of guard tokens in relation to the user-visible pointer. */
/* 用于标记已使用/已释放块的魔术标记。 */
#define ALLOC_MAGIC_C1 0xFF00FF00 /* 已使用头部(双字) */
#define ALLOC_MAGIC_F 0xFE00FE00 /* 已释放头部(双字) */
#define ALLOC_MAGIC_C2 0xF0 /* 已使用尾部(字节) */
/* 与用户可见指针相关的保护标记的位置。 */
#define ALLOC_C1(_ptr) (((u32*)(_ptr))[-2])
#define ALLOC_S(_ptr) (((u32*)(_ptr))[-1])
#define ALLOC_C2(_ptr) (((u8*)(_ptr))[ALLOC_S(_ptr)])
@ -77,15 +71,13 @@
#define ALLOC_OFF_HEAD 8
#define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1)
/* Allocator increments for ck_realloc_block(). */
/* ck_realloc_block()的分配器增量。 */
#define ALLOC_BLK_INC 256
/* Sanity-checking macros for pointers. */
/* 用于指针的合理性检查宏。 */
#define CHECK_PTR(_p) do { \
if (_p) { \
if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\
if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) { \
if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \
ABORT("Use after free."); \
else ABORT("Corrupted head alloc canary."); \
@ -101,246 +93,206 @@
_tmp; \
})
/* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized
requests. */
/* 分配一个缓冲区明确不将其清零。对于零大小的请求返回NULL。 */
static inline void* DFL_ck_alloc_nozero(u32 size) {
void* ret;
void* ret;
if (!size) return NULL;
if (!size) return NULL;
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
ret += ALLOC_OFF_HEAD;
ret += ALLOC_OFF_HEAD;
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
return ret;
return ret;
}
/* Allocate a buffer, returning zeroed memory. */
/* 分配一个缓冲区,返回清零后的内存。 */
static inline void* DFL_ck_alloc(u32 size) {
void* mem;
void* mem;
if (!size) return NULL;
mem = DFL_ck_alloc_nozero(size);
if (!size) return NULL;
mem = DFL_ck_alloc_nozero(size);
return memset(mem, 0, size);
return memset(mem, 0, size);
}
/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD
is set, the old memory will be also clobbered with 0xFF. */
/* 释放内存检查是否重复释放和堆损坏。当DEBUG_BUILD被设置时
0xFF */
static inline void DFL_ck_free(void* mem) {
if (!mem) return; /* 如果指针为空,不执行任何操作 */
if (!mem) return;
CHECK_PTR(mem);
#ifdef DEBUG_BUILD
/* Catch pointer issues sooner. */
memset(mem, 0xFF, ALLOC_S(mem));
CHECK_PTR(mem); /* 检查是否重复释放和堆损坏 */
#ifdef DEBUG_BUILD /* 如果是调试构建用0xFF覆盖内存 */
/* 尽早捕捉指针问题。 */
memset(mem, 0xFF, ALLOC_S(mem)); /* 用0xFF覆盖内存 */
#endif /* DEBUG_BUILD */
ALLOC_C1(mem) = ALLOC_MAGIC_F;
free(mem - ALLOC_OFF_HEAD);
ALLOC_C1(mem) = ALLOC_MAGIC_F; /* 标记内存为已释放 */
free(mem - ALLOC_OFF_HEAD); /* 释放内存,调整头偏移 */
}
/* Re-allocate a buffer, checking for issues and zeroing any newly-added tail.
With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the
old memory is clobbered with 0xFF. */
/* 重新分配缓冲区,检查问题并清零任何新添加的尾部。
DEBUG_BUILD0xFF */
static inline void* DFL_ck_realloc(void* orig, u32 size) {
void* ret;
u32 old_size = 0;
void* ret;
u32 old_size = 0;
if (!size) {
DFL_ck_free(orig);
return NULL;
}
if (orig) {
if (!size) {
DFL_ck_free(orig); /* 如果新大小为0释放原始内存 */
return NULL;
}
CHECK_PTR(orig);
if (orig) {
CHECK_PTR(orig); /* 检查是否重复释放和堆损坏 */
#ifndef DEBUG_BUILD
ALLOC_C1(orig) = ALLOC_MAGIC_F;
#ifndef DEBUG_BUILD /* 在非调试构建中,可以重用内存 */
ALLOC_C1(orig) = ALLOC_MAGIC_F; /* 标记内存为已释放 */
#endif /* !DEBUG_BUILD */
old_size = ALLOC_S(orig);
orig -= ALLOC_OFF_HEAD;
ALLOC_CHECK_SIZE(old_size);
}
ALLOC_CHECK_SIZE(size);
#ifndef DEBUG_BUILD
ret = realloc(orig, size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
#else
/* Catch pointer issues sooner: force relocation and make sure that the
original buffer is wiped. */
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
old_size = ALLOC_S(orig); /* 获取原始大小 */
orig -= ALLOC_OFF_HEAD; /* 调整指针以适应头部偏移 */
if (orig) {
memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size));
memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size);
ALLOC_CHECK_SIZE(old_size); /* 检查原始大小是否有效 */
}
ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F;
ALLOC_CHECK_SIZE(size); /* 检查新大小是否有效 */
free(orig);
#ifndef DEBUG_BUILD /* 在非调试构建中,尝试原地调整内存大小 */
ret = realloc(orig, size + ALLOC_OFF_TOTAL); /* 重新分配内存 */
ALLOC_CHECK_RESULT(ret, size); /* 检查重新分配是否成功 */
#else /* 在调试构建中,总是分配新内存并清除旧内存 */
/* 尽早捕捉指针问题:强制重新定位,并确保旧缓冲区被清除。 */
}
ret = malloc(size + ALLOC_OFF_TOTAL); /* 分配新内存 */
ALLOC_CHECK_RESULT(ret, size); /* 检查分配是否成功 */
if (orig) {
memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size)); /* 将数据复制到新内存 */
memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size); /* 用0xFF覆盖旧内存 */
ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F; /* 标记旧内存为已释放 */
free(orig); /* 释放旧内存 */
}
#endif /* ^!DEBUG_BUILD */
ret += ALLOC_OFF_HEAD;
ret += ALLOC_OFF_HEAD; /* 调整指针以适应头部偏移 */
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
ALLOC_C1(ret) = ALLOC_MAGIC_C1; /* 标记内存为已使用 */
ALLOC_S(ret) = size; /* 存储内存块的大小 */
ALLOC_C2(ret) = ALLOC_MAGIC_C2; /* 标记内存块的结尾 */
if (size > old_size)
memset(ret + old_size, 0, size - old_size);
return ret;
if (size > old_size) /* 如果新大小更大,清零新的尾部 */
memset(ret + old_size, 0, size - old_size);
return ret; /* 返回(可能新的)内存块 */
}
/* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up
repeated small reallocs without complicating the user code). */
/* 以ALLOC_BLK_INC的增量重新分配缓冲区用于加速重复的小realloc操作而不需要复杂化用户代码。 */
static inline void* DFL_ck_realloc_block(void* orig, u32 size) {
#ifndef DEBUG_BUILD
if (orig) {
if (orig) {
CHECK_PTR(orig);
CHECK_PTR(orig); /* 检查原始指针是否有效 */
if (ALLOC_S(orig) >= size) return orig;
if (ALLOC_S(orig) >= size) return orig; /* 如果当前大小已满足需求则不进行realloc */
size += ALLOC_BLK_INC;
size += ALLOC_BLK_INC; /* 增加ALLOC_BLK_INC以减少频繁的小realloc操作 */
}
}
#endif /* !DEBUG_BUILD */
return DFL_ck_realloc(orig, size);
return DFL_ck_realloc(orig, size); /* 调用DFL_ck_realloc进行实际的realloc操作 */
}
/* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */
/* 创建一个包含字符串副本的缓冲区。对于NULL输入返回NULL。 */
static inline u8* DFL_ck_strdup(u8* str) {
void* ret;
u32 size;
void* ret;
u32 size;
if (!str) return NULL;
if (!str) return NULL; /* 如果输入字符串为空则返回NULL */
size = strlen((char*)str) + 1;
size = strlen((char*)str) + 1; /* 计算字符串长度加1为'\0'留空间) */
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
ALLOC_CHECK_SIZE(size); /* 检查分配大小是否超出限制 */
ret = malloc(size + ALLOC_OFF_TOTAL); /* 分配内存 */
ALLOC_CHECK_RESULT(ret, size); /* 检查内存分配是否成功 */
ret += ALLOC_OFF_HEAD;
ret += ALLOC_OFF_HEAD; /* 调整指针以适应头部偏移 */
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
ALLOC_C1(ret) = ALLOC_MAGIC_C1; /* 设置头部魔术标记 */
ALLOC_S(ret) = size; /* 存储分配的大小 */
ALLOC_C2(ret) = ALLOC_MAGIC_C2; /* 设置尾部魔术标记 */
return memcpy(ret, str, size);
return memcpy(ret, str, size); /* 复制字符串并返回新指针 */
}
/* Create a buffer with a copy of a memory block. Returns NULL for zero-sized
or NULL inputs. */
/* 创建一个包含内存块副本的缓冲区。对于零大小或NULL输入返回NULL。 */
static inline void* DFL_ck_memdup(void* mem, u32 size) {
void* ret;
if (!mem || !size) return NULL;
void* ret;
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
ret += ALLOC_OFF_HEAD;
if (!mem || !size) return NULL; /* 如果内存块为空或大小为零则返回NULL */
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
ALLOC_CHECK_SIZE(size); /* 检查分配大小是否超出限制 */
ret = malloc(size + ALLOC_OFF_TOTAL); /* 分配内存 */
ALLOC_CHECK_RESULT(ret, size); /* 检查内存分配是否成功 */
return memcpy(ret, mem, size);
ret += ALLOC_OFF_HEAD; /* 调整指针以适应头部偏移 */
}
ALLOC_C1(ret) = ALLOC_MAGIC_C1; /* 设置头部魔术标记 */
ALLOC_S(ret) = size; /* 存储分配的大小 */
ALLOC_C2(ret) = ALLOC_MAGIC_C2; /* 设置尾部魔术标记 */
return memcpy(ret, mem, size); /* 复制内存块并返回新指针 */
/* Create a buffer with a block of text, appending a NUL terminator at the end.
Returns NULL for zero-sized or NULL inputs. */
}
/* 创建一个包含文本块的缓冲区并在末尾追加NUL终止符。对于零大小或NULL输入返回NULL。 */
static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {
u8* ret;
u8* ret;
if (!mem || !size) return NULL;
if (!mem || !size) return NULL; /* 如果内存块为空或大小为零则返回NULL */
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL + 1);
ALLOC_CHECK_RESULT(ret, size);
ret += ALLOC_OFF_HEAD;
ALLOC_CHECK_SIZE(size); /* 检查分配大小是否超出限制 */
ret = malloc(size + ALLOC_OFF_TOTAL + 1); /* 分配内存,额外+1用于NUL终止符 */
ALLOC_CHECK_RESULT(ret, size); /* 检查内存分配是否成功 */
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
ret += ALLOC_OFF_HEAD; /* 调整指针以适应头部偏移 */
memcpy(ret, mem, size);
ret[size] = 0;
ALLOC_C1(ret) = ALLOC_MAGIC_C1; /* 设置头部魔术标记 */
ALLOC_S(ret) = size; /* 存储分配的大小 */
ALLOC_C2(ret) = ALLOC_MAGIC_C2; /* 设置尾部魔术标记 */
return ret;
memcpy(ret, mem, size); /* 复制内存块 */
ret[size] = 0; /* 设置NUL终止符 */
}
return ret; /* 返回新指针 */
}
#ifndef DEBUG_BUILD
/* In non-debug mode, we just do straightforward aliasing of the above functions
to user-visible names such as ck_alloc(). */
/* 在非调试模式下我们直接将上述函数别名为用户可见的名称如ck_alloc()。 */
#define ck_alloc DFL_ck_alloc
#define ck_alloc_nozero DFL_ck_alloc_nozero
@ -355,223 +307,191 @@ static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {
#else
/* In debugging mode, we also track allocations to detect memory leaks, and the
flow goes through one more layer of indirection. */
/* 在调试模式下,我们还跟踪内存分配以检测内存泄漏,这个过程会经历更多的间接层。 */
/* Alloc tracking data structures: */
/* 分配跟踪数据结构: */
#define ALLOC_BUCKETS 4096
#define ALLOC_BUCKETS 4096 /* 定义分配桶的数量 */
struct TRK_obj {
void *ptr;
char *file, *func;
u32 line;
void* ptr; /* 指向分配的内存块 */
char* file, * func; /* 分配时的文件名和函数名 */
u32 line; /* 分配时的代码行号 */
};
#ifdef AFL_MAIN
struct TRK_obj* TRK[ALLOC_BUCKETS];
u32 TRK_cnt[ALLOC_BUCKETS];
struct TRK_obj* TRK[ALLOC_BUCKETS]; /* 跟踪分配的内存对象数组 */
u32 TRK_cnt[ALLOC_BUCKETS]; /* 每个桶中跟踪对象的数量 */
# define alloc_report() TRK_report()
# define alloc_report() TRK_report() /* 定义alloc_report宏为TRK_report函数 */
#else
extern struct TRK_obj* TRK[ALLOC_BUCKETS];
extern u32 TRK_cnt[ALLOC_BUCKETS];
extern struct TRK_obj* TRK[ALLOC_BUCKETS]; /* 外部声明跟踪分配的内存对象数组 */
extern u32 TRK_cnt[ALLOC_BUCKETS]; /* 外部声明每个桶中跟踪对象的数量 */
# define alloc_report()
# define alloc_report() /* 在非AFL_MAIN环境下alloc_report宏为空 */
#endif /* ^AFL_MAIN */
/* Bucket-assigning function for a given pointer: */
#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS)
/* 为给定指针分配桶的函数: */
#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS) /* 定义桶分配宏 */
/* Add a new entry to the list of allocated objects. */
/* 将新分配的内存对象添加到跟踪列表中。 */
static inline void TRK_alloc_buf(void* ptr, const char* file, const char* func,
u32 line) {
u32 i, bucket;
u32 line) {
u32 i, bucket;
if (!ptr) return;
if (!ptr) return; /* 如果指针为空,则返回 */
bucket = TRKH(ptr);
bucket = TRKH(ptr); /* 获取桶编号 */
/* Find a free slot in the list of entries for that bucket. */
/* 在该桶的条目列表中找到一个空闲位置。 */
for (i = 0; i < TRK_cnt[bucket]; i++)
if (!TRK[bucket][i].ptr) {
TRK[bucket][i].ptr = ptr;
TRK[bucket][i].file = (char*)file;
TRK[bucket][i].func = (char*)func;
TRK[bucket][i].line = line;
return;
}
/* No space available - allocate more. */
for (i = 0; i < TRK_cnt[bucket]; i++)
if (!TRK[bucket][i].ptr) { /* 如果找到空闲位置 */
TRK[bucket][i].ptr = ptr;
TRK[bucket][i].file = (char*)file;
TRK[bucket][i].func = (char*)func;
TRK[bucket][i].line = line;
return;
}
TRK[bucket] = DFL_ck_realloc_block(TRK[bucket],
(TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj));
/* 没有可用空间 - 分配更多空间。 */
TRK[bucket][i].ptr = ptr;
TRK[bucket][i].file = (char*)file;
TRK[bucket][i].func = (char*)func;
TRK[bucket][i].line = line;
TRK[bucket] = DFL_ck_realloc_block(TRK[bucket],
(TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj)); /* 重新分配桶的大小 */
TRK_cnt[bucket]++;
TRK[bucket][i].ptr = ptr;
TRK[bucket][i].file = (char*)file;
TRK[bucket][i].func = (char*)func;
TRK[bucket][i].line = line;
TRK_cnt[bucket]++; /* 更新桶中条目的数量 */
}
/* Remove entry from the list of allocated objects. */
/* 从分配的内存对象列表中移除条目。 */
static inline void TRK_free_buf(void* ptr, const char* file, const char* func,
u32 line) {
u32 i, bucket;
if (!ptr) return;
u32 line) {
u32 i, bucket;
bucket = TRKH(ptr);
if (!ptr) return; /* 如果指针为空,则返回 */
/* Find the element on the list... */
bucket = TRKH(ptr); /* 获取桶编号 */
for (i = 0; i < TRK_cnt[bucket]; i++)
/* 在列表中找到该元素... */
if (TRK[bucket][i].ptr == ptr) {
TRK[bucket][i].ptr = 0;
return;
}
WARNF("ALLOC: Attempt to free non-allocated memory in %s (%s:%u)",
func, file, line);
for (i = 0; i < TRK_cnt[bucket]; i++)
if (TRK[bucket][i].ptr == ptr) { /* 如果找到匹配的指针 */
TRK[bucket][i].ptr = 0; /* 将指针设置为NULL */
return;
}
WARNF("ALLOC: Attempt to free non-allocated memory in %s (%s:%u)",
func, file, line); /* 警告:尝试释放未分配的内存 */
}
/* Do a final report on all non-deallocated objects. */
/* 对所有未释放的对象进行最终报告。 */
static inline void TRK_report(void) {
u32 i, bucket;
u32 i, bucket;
fflush(0);
for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)
for (i = 0; i < TRK_cnt[bucket]; i++)
if (TRK[bucket][i].ptr)
WARNF("ALLOC: Memory never freed, created in %s (%s:%u)",
TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line);
fflush(0); /* 清空输出缓冲区 */
for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)
for (i = 0; i < TRK_cnt[bucket]; i++)
if (TRK[bucket][i].ptr) /* 如果指针不为空 */
WARNF("ALLOC: Memory never freed, created in %s (%s:%u)",
TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line); /* 警告:内存从未释放 */
}
/* Simple wrappers for non-debugging functions: */
/* 非调试函数的简单包装器: */
static inline void* TRK_ck_alloc(u32 size, const char* file, const char* func,
u32 line) {
void* ret = DFL_ck_alloc(size);
TRK_alloc_buf(ret, file, func, line);
return ret;
u32 line) {
void* ret = DFL_ck_alloc(size); /* 分配内存 */
TRK_alloc_buf(ret, file, func, line); /* 添加到跟踪列表 */
return ret;
}
static inline void* TRK_ck_realloc(void* orig, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_realloc(orig, size);
TRK_free_buf(orig, file, func, line);
TRK_alloc_buf(ret, file, func, line);
return ret;
const char* func, u32 line) {
void* ret = DFL_ck_realloc(orig, size); /* 重新分配内存 */
TRK_free_buf(orig, file, func, line); /* 从跟踪列表中移除 */
TRK_alloc_buf(ret, file, func, line); /* 添加到跟踪列表 */
return ret;
}
/* 重新分配内存块,同时更新跟踪信息。 */
static inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_realloc_block(orig, size);
TRK_free_buf(orig, file, func, line);
TRK_alloc_buf(ret, file, func, line);
return ret;
const char* func, u32 line) {
void* ret = DFL_ck_realloc_block(orig, size); /* 调用DFL_ck_realloc_block重新分配内存 */
TRK_free_buf(orig, file, func, line); /* 从跟踪列表中移除原始内存块 */
TRK_alloc_buf(ret, file, func, line); /* 将新内存块添加到跟踪列表 */
return ret; /* 返回新内存块 */
}
/* 复制字符串并分配内存,同时更新跟踪信息。 */
static inline void* TRK_ck_strdup(u8* str, const char* file, const char* func,
u32 line) {
void* ret = DFL_ck_strdup(str);
TRK_alloc_buf(ret, file, func, line);
return ret;
u32 line) {
void* ret = DFL_ck_strdup(str); /* 调用DFL_ck_strdup复制字符串 */
TRK_alloc_buf(ret, file, func, line); /* 将新内存块添加到跟踪列表 */
return ret; /* 返回新内存块 */
}
/* 复制内存块并分配内存,同时更新跟踪信息。 */
static inline void* TRK_ck_memdup(void* mem, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_memdup(mem, size);
TRK_alloc_buf(ret, file, func, line);
return ret;
const char* func, u32 line) {
void* ret = DFL_ck_memdup(mem, size); /* 调用DFL_ck_memdup复制内存块 */
TRK_alloc_buf(ret, file, func, line); /* 将新内存块添加到跟踪列表 */
return ret; /* 返回新内存块 */
}
/* 复制内存块并添加字符串终止符,同时更新跟踪信息。 */
static inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_memdup_str(mem, size);
TRK_alloc_buf(ret, file, func, line);
return ret;
const char* func, u32 line) {
void* ret = DFL_ck_memdup_str(mem, size); /* 调用DFL_ck_memdup_str复制内存块并添加终止符 */
TRK_alloc_buf(ret, file, func, line); /* 将新内存块添加到跟踪列表 */
return ret; /* 返回新内存块 */
}
/* 释放内存并更新跟踪信息。 */
static inline void TRK_ck_free(void* ptr, const char* file,
const char* func, u32 line) {
TRK_free_buf(ptr, file, func, line);
DFL_ck_free(ptr);
const char* func, u32 line) {
TRK_free_buf(ptr, file, func, line); /* 从跟踪列表中移除内存块 */
DFL_ck_free(ptr); /* 释放内存块 */
}
/* Aliasing user-facing names to tracking functions: */
/* 将用户可见的名称别名为跟踪函数: */
#define ck_alloc(_p1) \
TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_alloc宏为TRK_ck_alloc */
#define ck_alloc_nozero(_p1) \
TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_alloc_nozero(_p1, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_alloc_nozero宏为TRK_ck_alloc_nozero */
#define ck_realloc(_p1, _p2) \
TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_realloc宏为TRK_ck_realloc */
#define ck_realloc_block(_p1, _p2) \
TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_realloc_block宏为TRK_ck_realloc_block */
#define ck_strdup(_p1) \
TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_strdup宏为TRK_ck_strdup */
#define ck_memdup(_p1, _p2) \
TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_memdup宏为TRK_ck_memdup */
#define ck_memdup_str(_p1, _p2) \
TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_memdup_str宏为TRK_ck_memdup_str */
#define ck_free(_p1) \
TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__)
TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__) /* 定义ck_free宏为TRK_ck_free */
#endif /* ^!DEBUG_BUILD */
#endif /* ! _HAVE_ALLOC_INL_H */

Loading…
Cancel
Save