1 /*
2 * Memory allocation functions for testing
3 *
4 * Copyright (C) 2011-2021, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23
24 #if defined( HAVE_STDLIB_H ) || defined( WINAPI )
25 #include <stdlib.h>
26 #endif
27
28 #if defined( HAVE_GNU_DL_DLSYM ) && defined( __GNUC__ )
29 #define __USE_GNU
30 #include <dlfcn.h>
31 #undef __USE_GNU
32 #endif
33
34 #include "bde_test_memory.h"
35
36 #if defined( HAVE_BDE_TEST_MEMORY )
37
38 static void *(*bde_test_real_malloc)(size_t) = NULL;
39 static void *(*bde_test_real_memcpy)(void *, const void *, size_t) = NULL;
40 static void *(*bde_test_real_memset)(void *, int, size_t) = NULL;
41 static void *(*bde_test_real_realloc)(void *, size_t) = NULL;
42
43 int bde_test_malloc_attempts_before_fail = -1;
44 int bde_test_memcpy_attempts_before_fail = -1;
45 int bde_test_memset_attempts_before_fail = -1;
46 int bde_test_realloc_attempts_before_fail = -1;
47
48 /* Custom malloc for testing memory error cases
49 * Note this function might fail if compiled with optimation
50 * Returns a pointer to newly allocated data or NULL
51 */
malloc(size_t size)52 void *malloc(
53 size_t size )
54 {
55 void *ptr = NULL;
56
57 if( bde_test_real_malloc == NULL )
58 {
59 bde_test_real_malloc = dlsym(
60 RTLD_NEXT,
61 "malloc" );
62 }
63 if( bde_test_malloc_attempts_before_fail == 0 )
64 {
65 bde_test_malloc_attempts_before_fail = -1;
66
67 return( NULL );
68 }
69 else if( bde_test_malloc_attempts_before_fail > 0 )
70 {
71 bde_test_malloc_attempts_before_fail--;
72 }
73 ptr = bde_test_real_malloc(
74 size );
75
76 return( ptr );
77 }
78
79 /* Custom memcpy for testing memory error cases
80 * Note this function might fail if compiled with optimation and as a shared libary
81 * Returns a pointer to newly allocated data or NULL
82 */
memcpy(void * destination,const void * source,size_t size)83 void *memcpy(
84 void *destination,
85 const void *source,
86 size_t size )
87 {
88 if( bde_test_real_memcpy == NULL )
89 {
90 bde_test_real_memcpy = dlsym(
91 RTLD_NEXT,
92 "memcpy" );
93 }
94 if( bde_test_memcpy_attempts_before_fail == 0 )
95 {
96 bde_test_memcpy_attempts_before_fail = -1;
97
98 return( NULL );
99 }
100 else if( bde_test_memcpy_attempts_before_fail > 0 )
101 {
102 bde_test_memcpy_attempts_before_fail--;
103 }
104 destination = bde_test_real_memcpy(
105 destination,
106 source,
107 size );
108
109 return( destination );
110 }
111
112 /* Custom memset for testing memory error cases
113 * Note this function might fail if compiled with optimation and as a shared libary
114 * Returns a pointer to newly allocated data or NULL
115 */
memset(void * ptr,int constant,size_t size)116 void *memset(
117 void *ptr,
118 int constant,
119 size_t size )
120 {
121 if( bde_test_real_memset == NULL )
122 {
123 bde_test_real_memset = dlsym(
124 RTLD_NEXT,
125 "memset" );
126 }
127 if( bde_test_memset_attempts_before_fail == 0 )
128 {
129 bde_test_memset_attempts_before_fail = -1;
130
131 return( NULL );
132 }
133 else if( bde_test_memset_attempts_before_fail > 0 )
134 {
135 bde_test_memset_attempts_before_fail--;
136 }
137 ptr = bde_test_real_memset(
138 ptr,
139 constant,
140 size );
141
142 return( ptr );
143 }
144
145 /* Custom realloc for testing memory error cases
146 * Note this function might fail if compiled with optimation
147 * Returns a pointer to reallocated data or NULL
148 */
realloc(void * ptr,size_t size)149 void *realloc(
150 void *ptr,
151 size_t size )
152 {
153 if( bde_test_real_realloc == NULL )
154 {
155 bde_test_real_realloc = dlsym(
156 RTLD_NEXT,
157 "realloc" );
158 }
159 if( bde_test_realloc_attempts_before_fail == 0 )
160 {
161 bde_test_realloc_attempts_before_fail = -1;
162
163 return( NULL );
164 }
165 else if( bde_test_realloc_attempts_before_fail > 0 )
166 {
167 bde_test_realloc_attempts_before_fail--;
168 }
169 ptr = bde_test_real_realloc(
170 ptr,
171 size );
172
173 return( ptr );
174 }
175
176 #endif /* defined( HAVE_BDE_TEST_MEMORY ) */
177
178