]>
Commit | Line | Data |
---|---|---|
ce019275 WM |
1 | /* Copyright (C) 2007-2010 Open Information Security Foundation |
2 | * | |
3 | * You can copy, redistribute or modify this Program under the terms of | |
4 | * the GNU General Public License version 2 as published by the Free | |
5 | * Software Foundation. | |
6 | * | |
7 | * This program is distributed in the hope that it will be useful, | |
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | * GNU General Public License for more details. | |
11 | * | |
12 | * You should have received a copy of the GNU General Public License | |
13 | * version 2 along with this program; if not, write to the Free Software | |
14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
15 | * 02110-1301, USA. | |
16 | */ | |
17 | ||
25a3a5c6 | 18 | /** |
ce019275 | 19 | * \file |
25a3a5c6 PR |
20 | * |
21 | * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com> | |
22 | * | |
ce019275 WM |
23 | * Utility Macros for memory management |
24 | * | |
25 | * \todo Add wrappers for functions that allocate/free memory here. | |
25a3a5c6 PR |
26 | * Currently we have malloc, calloc, realloc, strdup and free, |
27 | * but there are more. | |
28 | */ | |
29 | ||
692eb935 VJ |
30 | #ifndef __UTIL_MEM_H__ |
31 | #define __UTIL_MEM_H__ | |
25a3a5c6 | 32 | |
ee34c70a | 33 | #include "util-atomic.h" |
55da9787 VJ |
34 | |
35 | #if defined(_WIN32) || defined(__WIN32) | |
36 | #include "mm_malloc.h" | |
37 | #endif | |
38 | ||
ee34c70a | 39 | SC_ATOMIC_EXTERN(unsigned int, engine_stage); |
76af1b04 | 40 | |
25a3a5c6 PR |
41 | /* Use this only if you want to debug memory allocation and free() |
42 | * It will log a lot of lines more, so think that is a performance killer */ | |
43 | ||
44 | /* Uncomment this if you want to print memory allocations and free's() */ | |
692eb935 VJ |
45 | //#define DBG_MEM_ALLOC |
46 | ||
47 | #ifdef DBG_MEM_ALLOC | |
25a3a5c6 PR |
48 | |
49 | /* Uncomment this if you want to print mallocs at the startup (recommended) */ | |
9f4fae5b | 50 | #define DBG_MEM_ALLOC_SKIP_STARTUP |
25a3a5c6 PR |
51 | |
52 | #define SCMalloc(a) ({ \ | |
53 | void *ptrmem = NULL; \ | |
692eb935 | 54 | extern size_t global_mem; \ |
25a3a5c6 | 55 | extern uint8_t print_mem_flag; \ |
692eb935 | 56 | \ |
ed69eeab | 57 | ptrmem = malloc((a)); \ |
58 | if (ptrmem == NULL && (a) > 0) { \ | |
692eb935 | 59 | SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed: %s, while trying " \ |
ed69eeab | 60 | "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ |
76af1b04 PR |
61 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
62 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ | |
63 | exit(EXIT_FAILURE); \ | |
64 | } \ | |
25a3a5c6 | 65 | } \ |
692eb935 | 66 | \ |
ed69eeab | 67 | global_mem += (a); \ |
25a3a5c6 | 68 | if (print_mem_flag == 1) \ |
bc55fb27 | 69 | SCLogInfo("SCMalloc return at %p of size %"PRIuMAX, \ |
ed69eeab | 70 | ptrmem, (uintmax_t)(a)); \ |
692eb935 | 71 | \ |
25a3a5c6 PR |
72 | (void*)ptrmem; \ |
73 | }) | |
74 | ||
75 | #define SCRealloc(x, a) ({ \ | |
76 | void *ptrmem = NULL; \ | |
692eb935 | 77 | extern size_t global_mem; \ |
25a3a5c6 | 78 | extern uint8_t print_mem_flag; \ |
692eb935 | 79 | \ |
ed69eeab | 80 | ptrmem = realloc((x), (a)); \ |
81 | if (ptrmem == NULL && (a) > 0) { \ | |
692eb935 | 82 | SCLogError(SC_ERR_MEM_ALLOC, "SCRealloc failed: %s, while trying " \ |
ed69eeab | 83 | "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ |
76af1b04 PR |
84 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
85 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ | |
86 | exit(EXIT_FAILURE); \ | |
87 | } \ | |
25a3a5c6 | 88 | } \ |
692eb935 | 89 | \ |
ed69eeab | 90 | global_mem += (a); \ |
25a3a5c6 | 91 | if (print_mem_flag == 1) \ |
bc55fb27 | 92 | SCLogInfo("SCRealloc return at %p (old:%p) of size %"PRIuMAX, \ |
ed69eeab | 93 | ptrmem, (x), (uintmax_t)(a)); \ |
692eb935 | 94 | \ |
25a3a5c6 PR |
95 | (void*)ptrmem; \ |
96 | }) | |
97 | ||
98 | #define SCCalloc(nm, a) ({ \ | |
99 | void *ptrmem = NULL; \ | |
692eb935 | 100 | extern size_t global_mem; \ |
25a3a5c6 | 101 | extern uint8_t print_mem_flag; \ |
692eb935 | 102 | \ |
ed69eeab | 103 | ptrmem = calloc((nm), (a)); \ |
104 | if (ptrmem == NULL && (a) > 0) { \ | |
692eb935 | 105 | SCLogError(SC_ERR_MEM_ALLOC, "SCCalloc failed: %s, while trying " \ |
bc55fb27 | 106 | "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)a); \ |
76af1b04 PR |
107 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
108 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ | |
109 | exit(EXIT_FAILURE); \ | |
110 | } \ | |
25a3a5c6 | 111 | } \ |
692eb935 | 112 | \ |
ed69eeab | 113 | global_mem += (a)*(nm); \ |
25a3a5c6 | 114 | if (print_mem_flag == 1) \ |
ed69eeab | 115 | SCLogInfo("SCCalloc return at %p of size %"PRIuMAX" (nm) %"PRIuMAX, \ |
116 | ptrmem, (uintmax_t)(a), (uintmax_t)(nm)); \ | |
692eb935 | 117 | \ |
25a3a5c6 PR |
118 | (void*)ptrmem; \ |
119 | }) | |
120 | ||
121 | #define SCStrdup(a) ({ \ | |
122 | char *ptrmem = NULL; \ | |
692eb935 | 123 | extern size_t global_mem; \ |
25a3a5c6 | 124 | extern uint8_t print_mem_flag; \ |
ed69eeab | 125 | size_t len = strlen((a)); \ |
692eb935 | 126 | \ |
ed69eeab | 127 | ptrmem = strdup((a)); \ |
06a65cb4 | 128 | if (ptrmem == NULL) { \ |
692eb935 | 129 | SCLogError(SC_ERR_MEM_ALLOC, "SCStrdup failed: %s, while trying " \ |
bc55fb27 | 130 | "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)len); \ |
76af1b04 PR |
131 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
132 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ | |
133 | exit(EXIT_FAILURE); \ | |
134 | } \ | |
25a3a5c6 | 135 | } \ |
692eb935 | 136 | \ |
25a3a5c6 PR |
137 | global_mem += len; \ |
138 | if (print_mem_flag == 1) \ | |
bc55fb27 VJ |
139 | SCLogInfo("SCStrdup return at %p of size %"PRIuMAX, \ |
140 | ptrmem, (uintmax_t)len); \ | |
692eb935 | 141 | \ |
25a3a5c6 PR |
142 | (void*)ptrmem; \ |
143 | }) | |
144 | ||
145 | #define SCFree(a) ({ \ | |
146 | extern uint8_t print_mem_flag; \ | |
147 | if (print_mem_flag == 1) \ | |
ed69eeab | 148 | SCLogInfo("SCFree at %p", (a)); \ |
149 | free((a)); \ | |
25a3a5c6 PR |
150 | }) |
151 | ||
ed69eeab | 152 | #else /* !DBG_MEM_ALLOC */ |
25d1b6fe | 153 | |
692eb935 | 154 | #define SCMalloc(a) ({ \ |
76af1b04 PR |
155 | void *ptrmem = NULL; \ |
156 | \ | |
ed69eeab | 157 | ptrmem = malloc((a)); \ |
25d1b6fe | 158 | if (ptrmem == NULL) { \ |
76af1b04 | 159 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
11bdf483 | 160 | uintmax_t scmalloc_size_ = (uintmax_t)(a); \ |
25d1b6fe | 161 | SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed: %s, while trying " \ |
11bdf483 | 162 | "to allocate %"PRIuMAX" bytes", strerror(errno), scmalloc_size_); \ |
76af1b04 PR |
163 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ |
164 | exit(EXIT_FAILURE); \ | |
165 | } \ | |
692eb935 VJ |
166 | } \ |
167 | (void*)ptrmem; \ | |
168 | }) | |
169 | ||
170 | #define SCRealloc(x, a) ({ \ | |
76af1b04 PR |
171 | void *ptrmem = NULL; \ |
172 | \ | |
ed69eeab | 173 | ptrmem = realloc((x), (a)); \ |
25d1b6fe | 174 | if (ptrmem == NULL) { \ |
76af1b04 | 175 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
25d1b6fe | 176 | SCLogError(SC_ERR_MEM_ALLOC, "SCRealloc failed: %s, while trying " \ |
ed69eeab | 177 | "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ |
76af1b04 PR |
178 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ |
179 | exit(EXIT_FAILURE); \ | |
180 | } \ | |
692eb935 VJ |
181 | } \ |
182 | (void*)ptrmem; \ | |
183 | }) | |
184 | ||
185 | #define SCCalloc(nm, a) ({ \ | |
76af1b04 PR |
186 | void *ptrmem = NULL; \ |
187 | \ | |
ed69eeab | 188 | ptrmem = calloc((nm), (a)); \ |
25d1b6fe | 189 | if (ptrmem == NULL) { \ |
76af1b04 | 190 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
25d1b6fe | 191 | SCLogError(SC_ERR_MEM_ALLOC, "SCCalloc failed: %s, while trying " \ |
ed69eeab | 192 | "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ |
76af1b04 PR |
193 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ |
194 | exit(EXIT_FAILURE); \ | |
195 | } \ | |
692eb935 VJ |
196 | } \ |
197 | (void*)ptrmem; \ | |
198 | }) | |
199 | ||
200 | #define SCStrdup(a) ({ \ | |
76af1b04 | 201 | char *ptrmem = NULL; \ |
76af1b04 | 202 | \ |
ed69eeab | 203 | ptrmem = strdup((a)); \ |
06a65cb4 | 204 | if (ptrmem == NULL) { \ |
76af1b04 | 205 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
ed69eeab | 206 | size_t len = strlen((a)); \ |
25d1b6fe VJ |
207 | SCLogError(SC_ERR_MEM_ALLOC, "SCStrdup failed: %s, while trying " \ |
208 | "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)len); \ | |
76af1b04 PR |
209 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ |
210 | exit(EXIT_FAILURE); \ | |
211 | } \ | |
692eb935 VJ |
212 | } \ |
213 | (void*)ptrmem; \ | |
214 | }) | |
215 | ||
55da9787 VJ |
216 | #define SCFree(a) ({ \ |
217 | free(a); \ | |
218 | }) | |
219 | ||
220 | #if defined(__WIN32) || defined(_WIN32) | |
221 | ||
8f43670b VJ |
222 | /** \brief wrapper for allocing aligned mem |
223 | * \param a size | |
224 | * \param b alignement | |
225 | */ | |
226 | #define SCMallocAligned(a, b) ({ \ | |
227 | void *ptrmem = NULL; \ | |
228 | \ | |
55da9787 VJ |
229 | ptrmem = _mm_malloc((a), (b)); \ |
230 | if (ptrmem == NULL) { \ | |
8f43670b VJ |
231 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ |
232 | SCLogError(SC_ERR_MEM_ALLOC, "SCMallocAligned(posix_memalign) failed: %s, while trying " \ | |
ed69eeab | 233 | "to allocate %"PRIuMAX" bytes, alignment %"PRIuMAX, strerror(errno), (uintmax_t)(a), (uintmax_t)(b)); \ |
8f43670b VJ |
234 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ |
235 | exit(EXIT_FAILURE); \ | |
236 | } \ | |
237 | } \ | |
238 | (void*)ptrmem; \ | |
239 | }) | |
240 | ||
55da9787 VJ |
241 | /** \brief Free aligned memory |
242 | * | |
243 | * Not needed for mem alloc'd by posix_memalign, | |
244 | * but for possible future use of _mm_malloc needing | |
245 | * _mm_free. | |
246 | */ | |
247 | #define SCFreeAligned(a) ({ \ | |
248 | _mm_free(a); \ | |
249 | }) | |
250 | ||
251 | #else /* !win */ | |
252 | ||
253 | /** \brief wrapper for allocing aligned mem | |
254 | * \param a size | |
255 | * \param b alignement | |
256 | */ | |
257 | #define SCMallocAligned(a, b) ({ \ | |
258 | void *ptrmem = NULL; \ | |
259 | \ | |
260 | ptrmem = _mm_malloc((a), (b)); \ | |
261 | if (ptrmem == NULL) { \ | |
262 | if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ | |
263 | SCLogError(SC_ERR_MEM_ALLOC, "SCMallocAligned(posix_memalign) failed: %s, while trying " \ | |
264 | "to allocate %"PRIuMAX" bytes, alignment %"PRIuMAX, strerror(errno), (uintmax_t)a, (uintmax_t)b); \ | |
265 | SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ | |
266 | exit(EXIT_FAILURE); \ | |
267 | } \ | |
268 | } \ | |
269 | (void*)ptrmem; \ | |
76af1b04 | 270 | }) |
692eb935 | 271 | |
8f43670b VJ |
272 | /** \brief Free aligned memory |
273 | * | |
274 | * Not needed for mem alloc'd by posix_memalign, | |
275 | * but for possible future use of _mm_malloc needing | |
276 | * _mm_free. | |
277 | */ | |
278 | #define SCFreeAligned(a) ({ \ | |
ed69eeab | 279 | free((a)); \ |
8f43670b VJ |
280 | }) |
281 | ||
55da9787 | 282 | #endif /* __WIN32 */ |
8f43670b | 283 | |
692eb935 | 284 | #endif /* DBG_MEM_ALLOC */ |
25a3a5c6 | 285 | |
692eb935 | 286 | #endif /* __UTIL_MEM_H__ */ |
25a3a5c6 | 287 |