]> git.ipfire.org Git - people/ms/suricata.git/blame - src/util-mem.h
Various improvements to error handling found by Coverity.
[people/ms/suricata.git] / src / util-mem.h
CommitLineData
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 39SC_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