27
27
* - _aligned_offset_recalloc()
28
28
*/
29
29
30
+ #ifndef _WIN32
31
+ #define _GNU_SOURCE
32
+ #include <dlfcn.h>
33
+ #undef _GNU_SOURCE
34
+ #endif /* _WIN32 */
35
+
30
36
#if (defined PROXY_LIB_USES_JEMALLOC_POOL )
31
37
#include <umf/pools/pool_jemalloc.h>
32
38
#define umfPoolManagerOps umfJemallocPoolOps
@@ -103,6 +109,21 @@ static umf_memory_pool_handle_t Proxy_pool = NULL;
103
109
// it protects us from recursion in umfPool*()
104
110
static __TLS int was_called_from_umfPool = 0 ;
105
111
112
+ typedef void * (* system_aligned_alloc_t )(size_t alignment , size_t size );
113
+ typedef void * (* system_calloc_t )(size_t nmemb , size_t size );
114
+ typedef void (* system_free_t )(void * ptr );
115
+ typedef void * (* system_malloc_t )(size_t size );
116
+ typedef size_t (* system_malloc_usable_size_t )(void * ptr );
117
+ typedef void * (* system_realloc_t )(void * ptr , size_t size );
118
+
119
+ static system_aligned_alloc_t system_aligned_alloc ;
120
+ static system_calloc_t system_calloc ;
121
+ static system_free_t system_free ;
122
+ static system_malloc_t system_malloc ;
123
+ static system_malloc_usable_size_t system_malloc_usable_size ;
124
+ static system_realloc_t system_realloc ;
125
+ static size_t threshold_value = 0 ;
126
+
106
127
/*****************************************************************************/
107
128
/*** The constructor and destructor of the proxy library *********************/
108
129
/*****************************************************************************/
@@ -149,16 +170,40 @@ void proxy_lib_create_common(void) {
149
170
LOG_ERR ("creating UMF pool manager failed" );
150
171
exit (-1 );
151
172
}
173
+
174
+ LOG_DEBUG ("proxy pool created" );
175
+
176
+ #ifndef _WIN32
177
+ * ((void * * )(& system_aligned_alloc )) = dlsym (RTLD_NEXT , "aligned_alloc" );
178
+ * ((void * * )(& system_calloc )) = dlsym (RTLD_NEXT , "calloc" );
179
+ * ((void * * )(& system_free )) = dlsym (RTLD_NEXT , "free" );
180
+ * ((void * * )(& system_malloc )) = dlsym (RTLD_NEXT , "malloc" );
181
+ * ((void * * )(& system_malloc_usable_size )) =
182
+ dlsym (RTLD_NEXT , "malloc_usable_size" );
183
+ * ((void * * )(& system_realloc )) = dlsym (RTLD_NEXT , "realloc" );
184
+
185
+ if (system_aligned_alloc && system_calloc && system_free && system_malloc &&
186
+ system_malloc_usable_size && system_realloc ) {
187
+ // TODO threshold_value will be read from the environment variable
188
+ threshold_value = 128 ;
189
+ LOG_DEBUG ("all system hooks found, threshold_value = %zu" ,
190
+ threshold_value );
191
+ } else {
192
+ LOG_WARN ("system hooks NOT found" );
193
+ }
194
+ #endif
195
+
152
196
// The UMF pool has just been created (Proxy_pool != NULL). Stop using
153
197
// the linear allocator and start using the UMF pool allocator from now on.
198
+ LOG_DEBUG ("proxy library initialized" );
154
199
}
155
200
156
201
void proxy_lib_destroy_common (void ) {
157
202
if (utils_is_running_in_proxy_lib ()) {
158
203
// We cannot destroy 'Base_alloc_leak' nor 'Proxy_pool' nor 'OS_memory_provider',
159
204
// because it could lead to use-after-free in the program's unloader
160
205
// (for example _dl_fini() on Linux).
161
- return ;
206
+ goto fini_proxy_lib_destroy_common ;
162
207
}
163
208
164
209
umf_memory_pool_handle_t pool = Proxy_pool ;
@@ -168,6 +213,10 @@ void proxy_lib_destroy_common(void) {
168
213
umf_memory_provider_handle_t provider = OS_memory_provider ;
169
214
OS_memory_provider = NULL ;
170
215
umfMemoryProviderDestroy (provider );
216
+ LOG_DEBUG ("proxy library destroyed" );
217
+
218
+ fini_proxy_lib_destroy_common :
219
+ LOG_DEBUG ("proxy library finalized" );
171
220
}
172
221
173
222
/*****************************************************************************/
@@ -246,6 +295,10 @@ static inline size_t ba_leak_pool_contains_pointer(void *ptr) {
246
295
/*****************************************************************************/
247
296
248
297
void * malloc (size_t size ) {
298
+ if (size < threshold_value ) {
299
+ return system_malloc (size );
300
+ }
301
+
249
302
if (!was_called_from_umfPool && Proxy_pool ) {
250
303
was_called_from_umfPool = 1 ;
251
304
void * ptr = umfPoolMalloc (Proxy_pool , size );
@@ -257,6 +310,10 @@ void *malloc(size_t size) {
257
310
}
258
311
259
312
void * calloc (size_t nmemb , size_t size ) {
313
+ if ((nmemb * size ) < threshold_value ) {
314
+ return system_calloc (nmemb , size );
315
+ }
316
+
260
317
if (!was_called_from_umfPool && Proxy_pool ) {
261
318
was_called_from_umfPool = 1 ;
262
319
void * ptr = umfPoolCalloc (Proxy_pool , nmemb , size );
@@ -276,15 +333,20 @@ void free(void *ptr) {
276
333
return ;
277
334
}
278
335
279
- if (Proxy_pool ) {
336
+ if (Proxy_pool && ( umfPoolByPtr ( ptr ) == Proxy_pool ) ) {
280
337
if (umfPoolFree (Proxy_pool , ptr ) != UMF_RESULT_SUCCESS ) {
281
338
LOG_ERR ("umfPoolFree() failed" );
282
- assert (0 );
283
339
}
284
340
return ;
285
341
}
286
342
287
- assert (0 );
343
+ if (threshold_value ) {
344
+ system_free (ptr );
345
+ return ;
346
+ }
347
+
348
+ LOG_ERR ("free() failed: %p" , ptr );
349
+
288
350
return ;
289
351
}
290
352
@@ -303,18 +365,27 @@ void *realloc(void *ptr, size_t size) {
303
365
return ba_leak_realloc (ptr , size , leak_pool_contains_pointer );
304
366
}
305
367
306
- if (Proxy_pool ) {
368
+ if (Proxy_pool && ( umfPoolByPtr ( ptr ) == Proxy_pool ) ) {
307
369
was_called_from_umfPool = 1 ;
308
370
void * new_ptr = umfPoolRealloc (Proxy_pool , ptr , size );
309
371
was_called_from_umfPool = 0 ;
310
372
return new_ptr ;
311
373
}
312
374
313
- assert (0 );
375
+ if (threshold_value ) {
376
+ return system_realloc (ptr , size );
377
+ }
378
+
379
+ LOG_ERR ("realloc() failed: %p" , ptr );
380
+
314
381
return NULL ;
315
382
}
316
383
317
384
void * aligned_alloc (size_t alignment , size_t size ) {
385
+ if (size < threshold_value ) {
386
+ return system_aligned_alloc (alignment , size );
387
+ }
388
+
318
389
if (!was_called_from_umfPool && Proxy_pool ) {
319
390
was_called_from_umfPool = 1 ;
320
391
void * ptr = umfPoolAlignedMalloc (Proxy_pool , size , alignment );
@@ -330,19 +401,28 @@ size_t _msize(void *ptr) {
330
401
#else
331
402
size_t malloc_usable_size (void * ptr ) {
332
403
#endif
333
-
334
- // a check to verify we are running the proxy library
404
+ // a check to verify if we are running the proxy library
335
405
if (ptr == (void * )0x01 ) {
336
406
return 0xDEADBEEF ;
337
407
}
338
408
339
- if (!was_called_from_umfPool && Proxy_pool ) {
409
+ if (ba_leak_pool_contains_pointer (ptr )) {
410
+ return 0 ; // unsupported in case of the ba_leak allocator
411
+ }
412
+
413
+ if (Proxy_pool && (umfPoolByPtr (ptr ) == Proxy_pool )) {
340
414
was_called_from_umfPool = 1 ;
341
415
size_t size = umfPoolMallocUsableSize (Proxy_pool , ptr );
342
416
was_called_from_umfPool = 0 ;
343
417
return size ;
344
418
}
345
419
420
+ if (threshold_value ) {
421
+ return system_malloc_usable_size (ptr );
422
+ }
423
+
424
+ LOG_ERR ("malloc_usable_size() failed: %p" , ptr );
425
+
346
426
return 0 ; // unsupported in this case
347
427
}
348
428
0 commit comments