2727 * - _aligned_offset_recalloc()
2828 */
2929
30+ #ifndef _WIN32
31+ #define _GNU_SOURCE
32+ #include <dlfcn.h>
33+ #undef _GNU_SOURCE
34+ #endif /* _WIN32 */
35+
3036#if (defined PROXY_LIB_USES_JEMALLOC_POOL )
3137#include <umf/pools/pool_jemalloc.h>
3238#define umfPoolManagerOps umfJemallocPoolOps
@@ -103,6 +109,21 @@ static umf_memory_pool_handle_t Proxy_pool = NULL;
103109// it protects us from recursion in umfPool*()
104110static __TLS int was_called_from_umfPool = 0 ;
105111
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+
106127/*****************************************************************************/
107128/*** The constructor and destructor of the proxy library *********************/
108129/*****************************************************************************/
@@ -149,16 +170,40 @@ void proxy_lib_create_common(void) {
149170 LOG_ERR ("creating UMF pool manager failed" );
150171 exit (-1 );
151172 }
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+
152196 // The UMF pool has just been created (Proxy_pool != NULL). Stop using
153197 // the linear allocator and start using the UMF pool allocator from now on.
198+ LOG_DEBUG ("proxy library initialized" );
154199}
155200
156201void proxy_lib_destroy_common (void ) {
157202 if (utils_is_running_in_proxy_lib ()) {
158203 // We cannot destroy 'Base_alloc_leak' nor 'Proxy_pool' nor 'OS_memory_provider',
159204 // because it could lead to use-after-free in the program's unloader
160205 // (for example _dl_fini() on Linux).
161- return ;
206+ goto fini_proxy_lib_destroy_common ;
162207 }
163208
164209 umf_memory_pool_handle_t pool = Proxy_pool ;
@@ -168,6 +213,10 @@ void proxy_lib_destroy_common(void) {
168213 umf_memory_provider_handle_t provider = OS_memory_provider ;
169214 OS_memory_provider = NULL ;
170215 umfMemoryProviderDestroy (provider );
216+ LOG_DEBUG ("proxy library destroyed" );
217+
218+ fini_proxy_lib_destroy_common :
219+ LOG_DEBUG ("proxy library finalized" );
171220}
172221
173222/*****************************************************************************/
@@ -246,6 +295,10 @@ static inline size_t ba_leak_pool_contains_pointer(void *ptr) {
246295/*****************************************************************************/
247296
248297void * malloc (size_t size ) {
298+ if (size < threshold_value ) {
299+ return system_malloc (size );
300+ }
301+
249302 if (!was_called_from_umfPool && Proxy_pool ) {
250303 was_called_from_umfPool = 1 ;
251304 void * ptr = umfPoolMalloc (Proxy_pool , size );
@@ -257,6 +310,10 @@ void *malloc(size_t size) {
257310}
258311
259312void * calloc (size_t nmemb , size_t size ) {
313+ if ((nmemb * size ) < threshold_value ) {
314+ return system_calloc (nmemb , size );
315+ }
316+
260317 if (!was_called_from_umfPool && Proxy_pool ) {
261318 was_called_from_umfPool = 1 ;
262319 void * ptr = umfPoolCalloc (Proxy_pool , nmemb , size );
@@ -276,15 +333,20 @@ void free(void *ptr) {
276333 return ;
277334 }
278335
279- if (Proxy_pool ) {
336+ if (Proxy_pool && ( umfPoolByPtr ( ptr ) == Proxy_pool ) ) {
280337 if (umfPoolFree (Proxy_pool , ptr ) != UMF_RESULT_SUCCESS ) {
281338 LOG_ERR ("umfPoolFree() failed" );
282- assert (0 );
283339 }
284340 return ;
285341 }
286342
287- assert (0 );
343+ if (threshold_value ) {
344+ system_free (ptr );
345+ return ;
346+ }
347+
348+ LOG_ERR ("free() failed: %p" , ptr );
349+
288350 return ;
289351}
290352
@@ -303,18 +365,27 @@ void *realloc(void *ptr, size_t size) {
303365 return ba_leak_realloc (ptr , size , leak_pool_contains_pointer );
304366 }
305367
306- if (Proxy_pool ) {
368+ if (Proxy_pool && ( umfPoolByPtr ( ptr ) == Proxy_pool ) ) {
307369 was_called_from_umfPool = 1 ;
308370 void * new_ptr = umfPoolRealloc (Proxy_pool , ptr , size );
309371 was_called_from_umfPool = 0 ;
310372 return new_ptr ;
311373 }
312374
313- assert (0 );
375+ if (threshold_value ) {
376+ return system_realloc (ptr , size );
377+ }
378+
379+ LOG_ERR ("realloc() failed: %p" , ptr );
380+
314381 return NULL ;
315382}
316383
317384void * aligned_alloc (size_t alignment , size_t size ) {
385+ if (size < threshold_value ) {
386+ return system_aligned_alloc (alignment , size );
387+ }
388+
318389 if (!was_called_from_umfPool && Proxy_pool ) {
319390 was_called_from_umfPool = 1 ;
320391 void * ptr = umfPoolAlignedMalloc (Proxy_pool , size , alignment );
@@ -330,19 +401,28 @@ size_t _msize(void *ptr) {
330401#else
331402size_t malloc_usable_size (void * ptr ) {
332403#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
335405 if (ptr == (void * )0x01 ) {
336406 return 0xDEADBEEF ;
337407 }
338408
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 )) {
340414 was_called_from_umfPool = 1 ;
341415 size_t size = umfPoolMallocUsableSize (Proxy_pool , ptr );
342416 was_called_from_umfPool = 0 ;
343417 return size ;
344418 }
345419
420+ if (threshold_value ) {
421+ return system_malloc_usable_size (ptr );
422+ }
423+
424+ LOG_ERR ("malloc_usable_size() failed: %p" , ptr );
425+
346426 return 0 ; // unsupported in this case
347427}
348428
0 commit comments