xref: /llvm-project/compiler-rt/lib/memprof/memprof_interceptors.cpp (revision 6dec33834d1fd89f16e271dde9607c1de9554144)
13d4bba30STeresa Johnson //===-- memprof_interceptors.cpp -----------------------------------------===//
23d4bba30STeresa Johnson //
33d4bba30STeresa Johnson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43d4bba30STeresa Johnson // See https://llvm.org/LICENSE.txt for license information.
53d4bba30STeresa Johnson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63d4bba30STeresa Johnson //
73d4bba30STeresa Johnson //===----------------------------------------------------------------------===//
83d4bba30STeresa Johnson //
93d4bba30STeresa Johnson // This file is a part of MemProfiler, a memory profiler.
103d4bba30STeresa Johnson //
113d4bba30STeresa Johnson // Intercept various libc functions.
123d4bba30STeresa Johnson //===----------------------------------------------------------------------===//
133d4bba30STeresa Johnson 
143d4bba30STeresa Johnson #include "memprof_interceptors.h"
153d4bba30STeresa Johnson #include "memprof_allocator.h"
163d4bba30STeresa Johnson #include "memprof_internal.h"
173d4bba30STeresa Johnson #include "memprof_mapping.h"
183d4bba30STeresa Johnson #include "memprof_stack.h"
193d4bba30STeresa Johnson #include "memprof_stats.h"
203d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_libc.h"
213d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_posix.h"
223d4bba30STeresa Johnson 
233d4bba30STeresa Johnson namespace __memprof {
243d4bba30STeresa Johnson 
253d4bba30STeresa Johnson #define MEMPROF_READ_STRING(s, n) MEMPROF_READ_RANGE((s), (n))
263d4bba30STeresa Johnson 
273d4bba30STeresa Johnson static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
283d4bba30STeresa Johnson #if SANITIZER_INTERCEPT_STRNLEN
293d4bba30STeresa Johnson   if (REAL(strnlen)) {
303d4bba30STeresa Johnson     return REAL(strnlen)(s, maxlen);
313d4bba30STeresa Johnson   }
323d4bba30STeresa Johnson #endif
333d4bba30STeresa Johnson   return internal_strnlen(s, maxlen);
343d4bba30STeresa Johnson }
353d4bba30STeresa Johnson 
363d4bba30STeresa Johnson void SetThreadName(const char *name) {
373d4bba30STeresa Johnson   MemprofThread *t = GetCurrentThread();
383d4bba30STeresa Johnson   if (t)
393d4bba30STeresa Johnson     memprofThreadRegistry().SetThreadName(t->tid(), name);
403d4bba30STeresa Johnson }
413d4bba30STeresa Johnson 
423d4bba30STeresa Johnson int OnExit() {
433d4bba30STeresa Johnson   // FIXME: ask frontend whether we need to return failure.
443d4bba30STeresa Johnson   return 0;
453d4bba30STeresa Johnson }
463d4bba30STeresa Johnson 
473d4bba30STeresa Johnson } // namespace __memprof
483d4bba30STeresa Johnson 
493d4bba30STeresa Johnson // ---------------------- Wrappers ---------------- {{{1
503d4bba30STeresa Johnson using namespace __memprof;
513d4bba30STeresa Johnson 
529a156f6bSStefan Schulze Frielinghaus DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, usize)
533d4bba30STeresa Johnson DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
543d4bba30STeresa Johnson 
553d4bba30STeresa Johnson #define COMMON_INTERCEPT_FUNCTION_VER(name, ver)                               \
563d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC_VER(name, ver)
57ad294e57SAlex Richardson #define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver)          \
58ad294e57SAlex Richardson   MEMPROF_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver)
593d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)                         \
603d4bba30STeresa Johnson   MEMPROF_WRITE_RANGE(ptr, size)
613d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)                          \
623d4bba30STeresa Johnson   MEMPROF_READ_RANGE(ptr, size)
633d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                               \
643d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, func);                                        \
653d4bba30STeresa Johnson   do {                                                                         \
663d4bba30STeresa Johnson     if (memprof_init_is_running)                                               \
673d4bba30STeresa Johnson       return REAL(func)(__VA_ARGS__);                                          \
683d4bba30STeresa Johnson     ENSURE_MEMPROF_INITED();                                                   \
693d4bba30STeresa Johnson   } while (false)
703d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path)                              \
713d4bba30STeresa Johnson   do {                                                                         \
723d4bba30STeresa Johnson   } while (false)
733d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd)                                 \
743d4bba30STeresa Johnson   do {                                                                         \
753d4bba30STeresa Johnson   } while (false)
763d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd)                                 \
773d4bba30STeresa Johnson   do {                                                                         \
783d4bba30STeresa Johnson   } while (false)
793d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd)                    \
803d4bba30STeresa Johnson   do {                                                                         \
813d4bba30STeresa Johnson   } while (false)
823d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
833d4bba30STeresa Johnson // Should be memprofThreadRegistry().SetThreadNameByUserId(thread, name)
843d4bba30STeresa Johnson // But memprof does not remember UserId's for threads (pthread_t);
853d4bba30STeresa Johnson // and remembers all ever existed threads, so the linear search by UserId
863d4bba30STeresa Johnson // can be slow.
873d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name)                 \
883d4bba30STeresa Johnson   do {                                                                         \
893d4bba30STeresa Johnson   } while (false)
903d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
913d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
923d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)
933d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED()
943d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!memprof_inited)
953d4bba30STeresa Johnson #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \
963d4bba30STeresa Johnson   if (MemprofThread *t = GetCurrentThread()) {                                 \
973d4bba30STeresa Johnson     *begin = t->tls_begin();                                                   \
983d4bba30STeresa Johnson     *end = t->tls_end();                                                       \
993d4bba30STeresa Johnson   } else {                                                                     \
1003d4bba30STeresa Johnson     *begin = *end = 0;                                                         \
1013d4bba30STeresa Johnson   }
1023d4bba30STeresa Johnson 
1033d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_common_interceptors.inc"
1043d4bba30STeresa Johnson 
1053d4bba30STeresa Johnson #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) MEMPROF_READ_RANGE(p, s)
1063d4bba30STeresa Johnson #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) MEMPROF_WRITE_RANGE(p, s)
1073d4bba30STeresa Johnson #define COMMON_SYSCALL_POST_READ_RANGE(p, s)                                   \
1083d4bba30STeresa Johnson   do {                                                                         \
1093d4bba30STeresa Johnson     (void)(p);                                                                 \
1103d4bba30STeresa Johnson     (void)(s);                                                                 \
1113d4bba30STeresa Johnson   } while (false)
1123d4bba30STeresa Johnson #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s)                                  \
1133d4bba30STeresa Johnson   do {                                                                         \
1143d4bba30STeresa Johnson     (void)(p);                                                                 \
1153d4bba30STeresa Johnson     (void)(s);                                                                 \
1163d4bba30STeresa Johnson   } while (false)
1173d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_common_syscalls.inc"
1183d4bba30STeresa Johnson 
1193d4bba30STeresa Johnson struct ThreadStartParam {
1203d4bba30STeresa Johnson   atomic_uintptr_t t;
1213d4bba30STeresa Johnson   atomic_uintptr_t is_registered;
1223d4bba30STeresa Johnson };
1233d4bba30STeresa Johnson 
1243d4bba30STeresa Johnson static thread_return_t THREAD_CALLING_CONV memprof_thread_start(void *arg) {
1253d4bba30STeresa Johnson   ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
1263d4bba30STeresa Johnson   MemprofThread *t = nullptr;
1273d4bba30STeresa Johnson   while ((t = reinterpret_cast<MemprofThread *>(
1283d4bba30STeresa Johnson               atomic_load(&param->t, memory_order_acquire))) == nullptr)
1293d4bba30STeresa Johnson     internal_sched_yield();
1303d4bba30STeresa Johnson   SetCurrentThread(t);
1313d4bba30STeresa Johnson   return t->ThreadStart(GetTid(), &param->is_registered);
1323d4bba30STeresa Johnson }
1333d4bba30STeresa Johnson 
1343d4bba30STeresa Johnson INTERCEPTOR(int, pthread_create, void *thread, void *attr,
1353d4bba30STeresa Johnson             void *(*start_routine)(void *), void *arg) {
1363d4bba30STeresa Johnson   EnsureMainThreadIDIsCorrect();
1373d4bba30STeresa Johnson   GET_STACK_TRACE_THREAD;
1383d4bba30STeresa Johnson   int detached = 0;
1393d4bba30STeresa Johnson   if (attr)
1403d4bba30STeresa Johnson     REAL(pthread_attr_getdetachstate)(attr, &detached);
1413d4bba30STeresa Johnson   ThreadStartParam param;
1423d4bba30STeresa Johnson   atomic_store(&param.t, 0, memory_order_relaxed);
1433d4bba30STeresa Johnson   atomic_store(&param.is_registered, 0, memory_order_relaxed);
1443d4bba30STeresa Johnson   int result;
1453d4bba30STeresa Johnson   {
1463d4bba30STeresa Johnson     // Ignore all allocations made by pthread_create: thread stack/TLS may be
1473d4bba30STeresa Johnson     // stored by pthread for future reuse even after thread destruction, and
1483d4bba30STeresa Johnson     // the linked list it's stored in doesn't even hold valid pointers to the
1493d4bba30STeresa Johnson     // objects, the latter are calculated by obscure pointer arithmetic.
1503d4bba30STeresa Johnson     result = REAL(pthread_create)(thread, attr, memprof_thread_start, &param);
1513d4bba30STeresa Johnson   }
1523d4bba30STeresa Johnson   if (result == 0) {
1533d4bba30STeresa Johnson     u32 current_tid = GetCurrentTidOrInvalid();
1543d4bba30STeresa Johnson     MemprofThread *t = MemprofThread::Create(start_routine, arg, current_tid,
1553d4bba30STeresa Johnson                                              &stack, detached);
1563d4bba30STeresa Johnson     atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
1573d4bba30STeresa Johnson     // Wait until the MemprofThread object is initialized and the
1583d4bba30STeresa Johnson     // ThreadRegistry entry is in "started" state.
1593d4bba30STeresa Johnson     while (atomic_load(&param.is_registered, memory_order_acquire) == 0)
1603d4bba30STeresa Johnson       internal_sched_yield();
1613d4bba30STeresa Johnson   }
1623d4bba30STeresa Johnson   return result;
1633d4bba30STeresa Johnson }
1643d4bba30STeresa Johnson 
1653d4bba30STeresa Johnson INTERCEPTOR(int, pthread_join, void *t, void **arg) {
166bd132411SEnna1   return REAL(pthread_join)(t, arg);
1673d4bba30STeresa Johnson }
1683d4bba30STeresa Johnson 
169f0f774ebSVitaly Buka DEFINE_INTERNAL_PTHREAD_FUNCTIONS
1703d4bba30STeresa Johnson 
1713d4bba30STeresa Johnson INTERCEPTOR(char *, index, const char *string, int c)
172175fcd6fSMarco Elver ALIAS(WRAP(strchr));
1733d4bba30STeresa Johnson 
1743d4bba30STeresa Johnson // For both strcat() and strncat() we need to check the validity of |to|
1753d4bba30STeresa Johnson // argument irrespective of the |from| length.
1763d4bba30STeresa Johnson INTERCEPTOR(char *, strcat, char *to, const char *from) {
1773d4bba30STeresa Johnson   void *ctx;
1783d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strcat);
1793d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
18040067b88SMichael Jones   uptr from_length = internal_strlen(from);
1813d4bba30STeresa Johnson   MEMPROF_READ_RANGE(from, from_length + 1);
18240067b88SMichael Jones   uptr to_length = internal_strlen(to);
1833d4bba30STeresa Johnson   MEMPROF_READ_STRING(to, to_length);
1843d4bba30STeresa Johnson   MEMPROF_WRITE_RANGE(to + to_length, from_length + 1);
1853d4bba30STeresa Johnson   return REAL(strcat)(to, from);
1863d4bba30STeresa Johnson }
1873d4bba30STeresa Johnson 
188*6dec3383SVitaly Buka INTERCEPTOR(char *, strncat, char *to, const char *from, usize size) {
1893d4bba30STeresa Johnson   void *ctx;
1903d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strncat);
1913d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
1923d4bba30STeresa Johnson   uptr from_length = MaybeRealStrnlen(from, size);
193*6dec3383SVitaly Buka   uptr copy_length = Min<uptr>(size, from_length + 1);
1943d4bba30STeresa Johnson   MEMPROF_READ_RANGE(from, copy_length);
19540067b88SMichael Jones   uptr to_length = internal_strlen(to);
1963d4bba30STeresa Johnson   MEMPROF_READ_STRING(to, to_length);
1973d4bba30STeresa Johnson   MEMPROF_WRITE_RANGE(to + to_length, from_length + 1);
1983d4bba30STeresa Johnson   return REAL(strncat)(to, from, size);
1993d4bba30STeresa Johnson }
2003d4bba30STeresa Johnson 
2013d4bba30STeresa Johnson INTERCEPTOR(char *, strcpy, char *to, const char *from) {
2023d4bba30STeresa Johnson   void *ctx;
2033d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strcpy);
2043d4bba30STeresa Johnson   if (memprof_init_is_running) {
2053d4bba30STeresa Johnson     return REAL(strcpy)(to, from);
2063d4bba30STeresa Johnson   }
2073d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
20840067b88SMichael Jones   uptr from_size = internal_strlen(from) + 1;
2093d4bba30STeresa Johnson   MEMPROF_READ_RANGE(from, from_size);
2103d4bba30STeresa Johnson   MEMPROF_WRITE_RANGE(to, from_size);
2113d4bba30STeresa Johnson   return REAL(strcpy)(to, from);
2123d4bba30STeresa Johnson }
2133d4bba30STeresa Johnson 
2143d4bba30STeresa Johnson INTERCEPTOR(char *, strdup, const char *s) {
2153d4bba30STeresa Johnson   void *ctx;
2163d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strdup);
2173d4bba30STeresa Johnson   if (UNLIKELY(!memprof_inited))
2183d4bba30STeresa Johnson     return internal_strdup(s);
2193d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
22040067b88SMichael Jones   uptr length = internal_strlen(s);
2213d4bba30STeresa Johnson   MEMPROF_READ_RANGE(s, length + 1);
2223d4bba30STeresa Johnson   GET_STACK_TRACE_MALLOC;
2233d4bba30STeresa Johnson   void *new_mem = memprof_malloc(length + 1, &stack);
2243d4bba30STeresa Johnson   REAL(memcpy)(new_mem, s, length + 1);
2253d4bba30STeresa Johnson   return reinterpret_cast<char *>(new_mem);
2263d4bba30STeresa Johnson }
2273d4bba30STeresa Johnson 
2283d4bba30STeresa Johnson INTERCEPTOR(char *, __strdup, const char *s) {
2293d4bba30STeresa Johnson   void *ctx;
2303d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strdup);
2313d4bba30STeresa Johnson   if (UNLIKELY(!memprof_inited))
2323d4bba30STeresa Johnson     return internal_strdup(s);
2333d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
23440067b88SMichael Jones   uptr length = internal_strlen(s);
2353d4bba30STeresa Johnson   MEMPROF_READ_RANGE(s, length + 1);
2363d4bba30STeresa Johnson   GET_STACK_TRACE_MALLOC;
2373d4bba30STeresa Johnson   void *new_mem = memprof_malloc(length + 1, &stack);
2383d4bba30STeresa Johnson   REAL(memcpy)(new_mem, s, length + 1);
2393d4bba30STeresa Johnson   return reinterpret_cast<char *>(new_mem);
2403d4bba30STeresa Johnson }
2413d4bba30STeresa Johnson 
242*6dec3383SVitaly Buka INTERCEPTOR(char *, strncpy, char *to, const char *from, usize size) {
2433d4bba30STeresa Johnson   void *ctx;
2443d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strncpy);
2453d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
246*6dec3383SVitaly Buka   uptr from_size = Min<uptr>(size, MaybeRealStrnlen(from, size) + 1);
2473d4bba30STeresa Johnson   MEMPROF_READ_RANGE(from, from_size);
2483d4bba30STeresa Johnson   MEMPROF_WRITE_RANGE(to, size);
2493d4bba30STeresa Johnson   return REAL(strncpy)(to, from, size);
2503d4bba30STeresa Johnson }
2513d4bba30STeresa Johnson 
2523d4bba30STeresa Johnson INTERCEPTOR(long, strtol, const char *nptr, char **endptr, int base) {
2533d4bba30STeresa Johnson   void *ctx;
2543d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strtol);
2553d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
2563d4bba30STeresa Johnson   char *real_endptr;
2573d4bba30STeresa Johnson   long result = REAL(strtol)(nptr, &real_endptr, base);
2583d4bba30STeresa Johnson   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2593d4bba30STeresa Johnson   return result;
2603d4bba30STeresa Johnson }
2613d4bba30STeresa Johnson 
2623d4bba30STeresa Johnson INTERCEPTOR(int, atoi, const char *nptr) {
2633d4bba30STeresa Johnson   void *ctx;
2643d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, atoi);
2653d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
2663d4bba30STeresa Johnson   char *real_endptr;
2673d4bba30STeresa Johnson   // "man atoi" tells that behavior of atoi(nptr) is the same as
2683d4bba30STeresa Johnson   // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
2693d4bba30STeresa Johnson   // parsed integer can't be stored in *long* type (even if it's
2703d4bba30STeresa Johnson   // different from int). So, we just imitate this behavior.
2713d4bba30STeresa Johnson   int result = REAL(strtol)(nptr, &real_endptr, 10);
2723d4bba30STeresa Johnson   FixRealStrtolEndptr(nptr, &real_endptr);
2733d4bba30STeresa Johnson   MEMPROF_READ_STRING(nptr, (real_endptr - nptr) + 1);
2743d4bba30STeresa Johnson   return result;
2753d4bba30STeresa Johnson }
2763d4bba30STeresa Johnson 
2773d4bba30STeresa Johnson INTERCEPTOR(long, atol, const char *nptr) {
2783d4bba30STeresa Johnson   void *ctx;
2793d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, atol);
2803d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
2813d4bba30STeresa Johnson   char *real_endptr;
2823d4bba30STeresa Johnson   long result = REAL(strtol)(nptr, &real_endptr, 10);
2833d4bba30STeresa Johnson   FixRealStrtolEndptr(nptr, &real_endptr);
2843d4bba30STeresa Johnson   MEMPROF_READ_STRING(nptr, (real_endptr - nptr) + 1);
2853d4bba30STeresa Johnson   return result;
2863d4bba30STeresa Johnson }
2873d4bba30STeresa Johnson 
2883d4bba30STeresa Johnson INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr, int base) {
2893d4bba30STeresa Johnson   void *ctx;
2903d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, strtoll);
2913d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
2923d4bba30STeresa Johnson   char *real_endptr;
2933d4bba30STeresa Johnson   long long result = REAL(strtoll)(nptr, &real_endptr, base);
2943d4bba30STeresa Johnson   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2953d4bba30STeresa Johnson   return result;
2963d4bba30STeresa Johnson }
2973d4bba30STeresa Johnson 
2983d4bba30STeresa Johnson INTERCEPTOR(long long, atoll, const char *nptr) {
2993d4bba30STeresa Johnson   void *ctx;
3003d4bba30STeresa Johnson   MEMPROF_INTERCEPTOR_ENTER(ctx, atoll);
3013d4bba30STeresa Johnson   ENSURE_MEMPROF_INITED();
3023d4bba30STeresa Johnson   char *real_endptr;
3033d4bba30STeresa Johnson   long long result = REAL(strtoll)(nptr, &real_endptr, 10);
3043d4bba30STeresa Johnson   FixRealStrtolEndptr(nptr, &real_endptr);
3053d4bba30STeresa Johnson   MEMPROF_READ_STRING(nptr, (real_endptr - nptr) + 1);
3063d4bba30STeresa Johnson   return result;
3073d4bba30STeresa Johnson }
3083d4bba30STeresa Johnson 
3093d4bba30STeresa Johnson // ---------------------- InitializeMemprofInterceptors ---------------- {{{1
3103d4bba30STeresa Johnson namespace __memprof {
3113d4bba30STeresa Johnson void InitializeMemprofInterceptors() {
3123d4bba30STeresa Johnson   static bool was_called_once;
3133d4bba30STeresa Johnson   CHECK(!was_called_once);
3143d4bba30STeresa Johnson   was_called_once = true;
3153d4bba30STeresa Johnson   InitializeCommonInterceptors();
3163d4bba30STeresa Johnson 
3173d4bba30STeresa Johnson   // Intercept str* functions.
3183d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(strcat);
3193d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(strcpy);
3203d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(strncat);
3213d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(strncpy);
3223d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(strdup);
3233d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(__strdup);
3243d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(index);
3253d4bba30STeresa Johnson 
3263d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(atoi);
3273d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(atol);
3283d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(strtol);
3293d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(atoll);
3303d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(strtoll);
3313d4bba30STeresa Johnson 
3323d4bba30STeresa Johnson   // Intercept threading-related functions
3333d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(pthread_create);
3343d4bba30STeresa Johnson   MEMPROF_INTERCEPT_FUNC(pthread_join);
3353d4bba30STeresa Johnson 
3363d4bba30STeresa Johnson   InitializePlatformInterceptors();
3373d4bba30STeresa Johnson 
3383d4bba30STeresa Johnson   VReport(1, "MemProfiler: libc interceptors initialized\n");
3393d4bba30STeresa Johnson }
3403d4bba30STeresa Johnson 
3413d4bba30STeresa Johnson } // namespace __memprof
342