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