LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
safe_memory.h
浏览该文件的文档.
1/**
2 * Copyright (C) 2026 HJimmyK(Jericho Knox)
3 *
4 * This file is part of LAMMP.
5 *
6 * LAMMP is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License (LGPL) as published
8 * by the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed WITHOUT ANY WARRANTY.
12 *
13 * See <https://www.gnu.org/licenses/>.
14 */
15
16#ifndef __LAMMP_SAFE_MEMORY_H__
17#define __LAMMP_SAFE_MEMORY_H__
18
19#include <stdarg.h>
20#include <stddef.h>
21#include <stdint.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26
27typedef struct {
28 uint64_t magic; // 魔数,用于验证有效性
29 size_t user_size; // 用户请求的大小
30 size_t total_size; // 总分配大小(含头部、用户内存、额外内存)
31 size_t extra_size; // 额外分配的内存大小
32 const char* func; // 分配发生的函数名
33 int line; // 分配发生的行号
34 uint32_t guard; // 尾哨兵
36
37#define MEM_MAGIC 0xDEADBEEFDEADBEEFULL // deadbeef
38#define MEM_GUARD 0xDEADBEEFUL // deadbeef
39#define EXTRA_MEM_PATTERN 0xAA // 额外内存填充模式
40
41#define ALIGNMENT LAMMP_MAX_ALIGN
42
43static inline size_t align_up(size_t size) {
44 return (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
45}
46
47/**
48 * @brief 找到指定模式的连续内存区域,并记录起始和结束位置。
49 */
50static inline void find_corruption_range(
51 const char* data,
52 unsigned char pattern,
53 size_t len,
54 int* first,
55 int* last,
56 int* count
57) {
58 *first = -1;
59 *last = -1;
60 *count = 0;
61
62 for (size_t i = 0; i < len; i++) {
63 if ((unsigned char)data[i] != pattern) {
64 (*count)++;
65 if (*first == -1)
66 *first = (int)i;
67 *last = (int)i;
68 }
69 }
70}
71
72/**
73 * @brief 检查额外内存区域是否被修改。
74 */
75static inline int check_extra_memory_overflow(mem_header* hdr, void* user_ptr, const char* check_func, int check_line) {
76 if (!hdr || !user_ptr || hdr->extra_size == 0)
77 return 0;
78
79 size_t aligned_user_size = align_up(hdr->user_size);
80 char* extra_start = (char*)user_ptr + aligned_user_size;
81
82 int first, last, count;
83 find_corruption_range(extra_start, EXTRA_MEM_PATTERN, hdr->extra_size, &first, &last, &count);
84
85 if (count > 0) {
86 char error_buf[640];
87 int offset = 0;
88 const int buf_size = sizeof(error_buf);
89
90#define SAFE_APPEND(...) \
91 do { \
92 if (offset < buf_size) { \
93 int n = snprintf(error_buf + offset, (size_t)(buf_size - offset), __VA_ARGS__); \
94 if (n > 0) \
95 offset += n; \
96 } \
97 } while (0)
98
99 SAFE_APPEND("Memory overflow (extra memory corruption) detected!%s", "\n");
100 SAFE_APPEND("Memory header:%s", "\n");
101 SAFE_APPEND(" allocated at: [%s]:%d\n", hdr->func, hdr->line);
102 SAFE_APPEND(" checked at: [%s]:%d\n", check_func, check_line);
103 SAFE_APPEND(" user size: %zu bytes\n", hdr->user_size);
104 SAFE_APPEND(" extra size: %zu bytes (%.0f%% of user size)\n", hdr->extra_size,
106 SAFE_APPEND(" user ptr: %p\n", user_ptr);
107 SAFE_APPEND(" extra memory: %p to %p\n", (void*)extra_start, (void*)(extra_start + hdr->extra_size - 1));
108 SAFE_APPEND(" corrupted range: offset %d to %d (total %d bytes)\n", first, last, count);
109 SAFE_APPEND("Likely cause: Buffer overflow beyond the end of the memory.%s", "\n");
110
111 error_buf[buf_size - 1] = '\0';
112 lmmp_abort(LAMMP_ERROR_OUT_OF_BOUNDS, error_buf, check_func, check_line);
113 return 1;
114 }
115 return 0;
116}
117
118/**
119 * @brief 检查内存块的完整性(包括头尾和额外内存区域)。
120 */
121static inline int check_memory_block_integrity(mem_header* hdr, void* user_ptr, const char* check_func, int check_line) {
122 if (!hdr || !user_ptr)
123 return 0;
124
125 if (hdr->magic != MEM_MAGIC || hdr->guard != MEM_GUARD) {
126 char error_buf[240];
127 snprintf(error_buf, sizeof(error_buf),
128 "Memory header corruption detected!\n"
129 " Magic: 0x%016llx (expected 0x%016llx)\n"
130 " Guard: 0x%08lx (expected 0x%08lx)\n"
131 "Possible overflow or underflow or invalid pointer.",
132 hdr->magic, MEM_MAGIC, (unsigned long)hdr->guard, MEM_GUARD);
133 lmmp_abort(LAMMP_ERROR_MEMORY_FREE_FAILURE, error_buf, check_func, check_line);
134 return 1;
135 }
136
137 return check_extra_memory_overflow(hdr, user_ptr, check_func, check_line);
138}
139
140/**
141 * @brief 调试版 malloc
142 * @param size 要分配的内存大小
143 * @param func 分配内存的函数名
144 * @param line 分配内存的行号
145 * @return 分配的内存块的指针
146 */
147static inline void* lmmp_alloc_debug(size_t size, const char* func, int line) {
148 if (size == 0)
149 return NULL;
150
151 size_t extra_size = (size * LAMMP_MEMORY_MORE_ALLOC_TIMES) / 10;
152 extra_size = align_up(extra_size);
153
154 size_t header_size = align_up(sizeof(mem_header));
155 size_t aligned_user_size = align_up(size);
156 size_t total_size = header_size + aligned_user_size + extra_size;
157
158 void* base = heap_alloc_func(total_size);
159 if (!base) {
160 char msg[128];
161 snprintf(msg, sizeof(msg), "Memory allocation failed (size: %zu bytes, extra: %zu bytes)", size, extra_size);
163 return NULL;
164 }
165
166 mem_header* hdr = (mem_header*)base;
167 void* user_ptr = (char*)base + header_size;
168 void* extra_mem = (char*)user_ptr + aligned_user_size;
169
171 hdr->user_size = size;
172 hdr->total_size = total_size;
173 hdr->extra_size = extra_size;
174 hdr->func = func;
175 hdr->line = line;
176 hdr->guard = MEM_GUARD;
177
178 memset(extra_mem, EXTRA_MEM_PATTERN, extra_size);
179
180 return user_ptr;
181}
182
183/**
184 * @brief 调试版 free
185 * @param ptr 指向要释放的内存块的指针
186 * @param func 分配内存的函数名
187 * @param line 分配内存的行号
188 */
189static inline void lmmp_free_debug(void* ptr, const char* func, int line) {
190 if (!ptr)
191 return;
192
193 size_t header_size = align_up(sizeof(mem_header));
194 mem_header* hdr = (mem_header*)((char*)ptr - header_size);
195
196 check_memory_block_integrity(hdr, ptr, func, line);
197
199}
200
201/**
202 * @brief 调试版 realloc
203 * @param ptr 指向要重新分配的内存块的指针
204 * @param new_size 新的内存大小
205 * @param func 分配内存的函数名
206 * @param line 分配内存的行号
207 * @return 新分配的内存块的指针
208 */
209static inline void* lmmp_realloc_debug(void* ptr, size_t new_size, const char* func, int line) {
210 if (!ptr)
211 return lmmp_alloc_debug(new_size, func, line);
212 if (new_size == 0) {
213 lmmp_abort(LAMMP_ERROR_MEMORY_ALLOC_FAILURE, "Reallocating zero bytes is not allowed.", func, line);
214 return NULL;
215 }
216
217 size_t header_size = align_up(sizeof(mem_header));
218 mem_header* old_hdr = (mem_header*)((char*)ptr - header_size);
219
220 check_memory_block_integrity(old_hdr, ptr, func, line);
221
222 void* new_ptr = lmmp_alloc_debug(new_size, func, line);
223 if (!new_ptr)
224 return NULL;
225
226 size_t copy_size = (old_hdr->user_size < new_size) ? old_hdr->user_size : new_size;
227 memcpy(new_ptr, ptr, copy_size);
228
229 lmmp_free_debug(ptr, func, line);
230 return new_ptr;
231}
232
233#undef SAFE_APPEND
234#undef MEM_MAGIC
235#undef MEM_GUARD
236#undef ALIGNMENT
237#undef EXTRA_MEM_PATTERN
238
239#endif // __LAMMP_SAFE_MEMORY_H__
void lmmp_abort(lmmp_error_t type, const char *msg, const char *func, int line)
LAMMP 全局退出函数,内部错误或断言失败时调用,若设置了全局退出函数,则会调用该函数,否则会调用默认的退出函数。
Definition abort.c:102
#define LAMMP_MEMORY_MORE_ALLOC_TIMES
Definition lmmp.h:51
@ LAMMP_ERROR_MEMORY_ALLOC_FAILURE
Definition lmmp.h:215
@ LAMMP_ERROR_MEMORY_FREE_FAILURE
Definition lmmp.h:216
@ LAMMP_ERROR_OUT_OF_BOUNDS
Definition lmmp.h:217
#define heap_alloc_func
Definition memory.c:35
#define heap_free_func
Definition memory.c:36
#define n
#define SAFE_APPEND(...)
size_t total_size
Definition safe_memory.h:30
static void * lmmp_realloc_debug(void *ptr, size_t new_size, const char *func, int line)
调试版 realloc
uint32_t guard
Definition safe_memory.h:34
static void find_corruption_range(const char *data, unsigned char pattern, size_t len, int *first, int *last, int *count)
找到指定模式的连续内存区域,并记录起始和结束位置。
Definition safe_memory.h:50
size_t user_size
Definition safe_memory.h:29
#define ALIGNMENT
Definition safe_memory.h:41
static int check_extra_memory_overflow(mem_header *hdr, void *user_ptr, const char *check_func, int check_line)
检查额外内存区域是否被修改。
Definition safe_memory.h:75
#define MEM_MAGIC
Definition safe_memory.h:37
#define EXTRA_MEM_PATTERN
Definition safe_memory.h:39
uint64_t magic
Definition safe_memory.h:28
static size_t align_up(size_t size)
Definition safe_memory.h:43
static int check_memory_block_integrity(mem_header *hdr, void *user_ptr, const char *check_func, int check_line)
检查内存块的完整性(包括头尾和额外内存区域)。
size_t extra_size
Definition safe_memory.h:31
static void * lmmp_alloc_debug(size_t size, const char *func, int line)
调试版 malloc
const char * func
Definition safe_memory.h:32
static void lmmp_free_debug(void *ptr, const char *func, int line)
调试版 free
#define MEM_GUARD
Definition safe_memory.h:38
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition safe_memory.h:27