*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
*/
#define _GNU_SOURCE
+/*
+ * Do _not_ define _LGPL_SOURCE because we don't want to create a
+ * circular dependency loop between this malloc wrapper, liburcu and
+ * libc.
+ */
#include <lttng/ust-dlfcn.h>
#include <sys/types.h>
#include <stdio.h>
#include <urcu/system.h>
#include <urcu/uatomic.h>
#include <urcu/compiler.h>
-#include <urcu/tls-compat.h>
#include <urcu/arch.h>
#include <lttng/align.h>
+#include <helper.h>
#define TRACEPOINT_DEFINE
#define TRACEPOINT_CREATE_PROBES
+#define TP_IP_PARAM ip
#include "ust_libc.h"
#define STATIC_CALLOC_LEN 4096
uatomic_set(&ust_malloc_lock, 0);
}
-#define calloc static_calloc
-#define pthread_mutex_lock ust_malloc_spin_lock
-#define pthread_mutex_unlock ust_malloc_spin_unlock
-static DEFINE_URCU_TLS(int, malloc_nesting);
-#undef ust_malloc_spin_unlock
-#undef ust_malloc_spin_lock
-#undef calloc
+/*
+ * Use initial-exec TLS model for the malloc_nesting nesting guard
+ * variable to ensure that the glibc implementation of the TLS access
+ * don't trigger infinite recursion by calling the memory allocator
+ * wrapper functions, which could happen with global-dynamic.
+ */
+static __thread __attribute__((tls_model("initial-exec"))) int malloc_nesting;
/*
* Static allocator to use when initially executing dlsym(). It keeps a
{
void *retval;
- URCU_TLS(malloc_nesting)++;
+ malloc_nesting++;
if (cur_alloc.malloc == NULL) {
lookup_all_symbols();
if (cur_alloc.malloc == NULL) {
}
}
retval = cur_alloc.malloc(size);
- if (URCU_TLS(malloc_nesting) == 1) {
- tracepoint(ust_libc, malloc, size, retval, __builtin_return_address(0));
+ if (malloc_nesting == 1) {
+ tracepoint(lttng_ust_libc, malloc,
+ size, retval, LTTNG_UST_CALLER_IP());
}
- URCU_TLS(malloc_nesting)--;
+ malloc_nesting--;
return retval;
}
void free(void *ptr)
{
- URCU_TLS(malloc_nesting)++;
+ malloc_nesting++;
/*
* Check whether the memory was allocated with
* static_calloc_align, in which case there is nothing to free.
goto end;
}
- if (URCU_TLS(malloc_nesting) == 1) {
- tracepoint(ust_libc, free, ptr, __builtin_return_address(0));
+ if (malloc_nesting == 1) {
+ tracepoint(lttng_ust_libc, free,
+ ptr, LTTNG_UST_CALLER_IP());
}
if (cur_alloc.free == NULL) {
}
cur_alloc.free(ptr);
end:
- URCU_TLS(malloc_nesting)--;
+ malloc_nesting--;
}
void *calloc(size_t nmemb, size_t size)
{
void *retval;
- URCU_TLS(malloc_nesting)++;
+ malloc_nesting++;
if (cur_alloc.calloc == NULL) {
lookup_all_symbols();
if (cur_alloc.calloc == NULL) {
}
}
retval = cur_alloc.calloc(nmemb, size);
- if (URCU_TLS(malloc_nesting) == 1) {
- tracepoint(ust_libc, calloc, nmemb, size, retval, __builtin_return_address(0));
+ if (malloc_nesting == 1) {
+ tracepoint(lttng_ust_libc, calloc,
+ nmemb, size, retval, LTTNG_UST_CALLER_IP());
}
- URCU_TLS(malloc_nesting)--;
+ malloc_nesting--;
return retval;
}
{
void *retval;
- URCU_TLS(malloc_nesting)++;
+ malloc_nesting++;
/*
* Check whether the memory was allocated with
* static_calloc_align, in which case there is nothing
}
retval = cur_alloc.realloc(ptr, size);
end:
- if (URCU_TLS(malloc_nesting) == 1) {
- tracepoint(ust_libc, realloc, ptr, size, retval, __builtin_return_address(0));
+ if (malloc_nesting == 1) {
+ tracepoint(lttng_ust_libc, realloc,
+ ptr, size, retval, LTTNG_UST_CALLER_IP());
}
- URCU_TLS(malloc_nesting)--;
+ malloc_nesting--;
return retval;
}
{
void *retval;
- URCU_TLS(malloc_nesting)++;
+ malloc_nesting++;
if (cur_alloc.memalign == NULL) {
lookup_all_symbols();
if (cur_alloc.memalign == NULL) {
}
}
retval = cur_alloc.memalign(alignment, size);
- if (URCU_TLS(malloc_nesting) == 1) {
- tracepoint(ust_libc, memalign, alignment, size, retval, __builtin_return_address(0));
+ if (malloc_nesting == 1) {
+ tracepoint(lttng_ust_libc, memalign,
+ alignment, size, retval,
+ LTTNG_UST_CALLER_IP());
}
- URCU_TLS(malloc_nesting)--;
+ malloc_nesting--;
return retval;
}
{
int retval;
- URCU_TLS(malloc_nesting)++;
+ malloc_nesting++;
if (cur_alloc.posix_memalign == NULL) {
lookup_all_symbols();
if (cur_alloc.posix_memalign == NULL) {
}
}
retval = cur_alloc.posix_memalign(memptr, alignment, size);
- if (URCU_TLS(malloc_nesting) == 1) {
- tracepoint(ust_libc, posix_memalign, *memptr, alignment, size,
- retval, __builtin_return_address(0));
+ if (malloc_nesting == 1) {
+ tracepoint(lttng_ust_libc, posix_memalign,
+ *memptr, alignment, size,
+ retval, LTTNG_UST_CALLER_IP());
}
- URCU_TLS(malloc_nesting)--;
+ malloc_nesting--;
return retval;
}