2013-05-20 19:01:40 +08:00
|
|
|
//=-- lsan_interceptors.cc ------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file is a part of LeakSanitizer.
|
|
|
|
// Interceptors for standalone LSan.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-11-18 18:33:15 +08:00
|
|
|
#include "interception/interception.h"
|
2013-05-20 19:01:40 +08:00
|
|
|
#include "sanitizer_common/sanitizer_allocator.h"
|
2018-06-06 02:02:09 +08:00
|
|
|
#include "sanitizer_common/sanitizer_allocator_report.h"
|
2013-05-20 19:01:40 +08:00
|
|
|
#include "sanitizer_common/sanitizer_atomic.h"
|
|
|
|
#include "sanitizer_common/sanitizer_common.h"
|
|
|
|
#include "sanitizer_common/sanitizer_flags.h"
|
|
|
|
#include "sanitizer_common/sanitizer_internal_defs.h"
|
|
|
|
#include "sanitizer_common/sanitizer_linux.h"
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#include "sanitizer_common/sanitizer_platform_interceptors.h"
|
2017-08-31 06:47:05 +08:00
|
|
|
#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
|
2013-05-20 19:01:40 +08:00
|
|
|
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
|
2017-04-14 01:28:52 +08:00
|
|
|
#include "sanitizer_common/sanitizer_posix.h"
|
2016-01-15 02:50:09 +08:00
|
|
|
#include "sanitizer_common/sanitizer_tls_get_addr.h"
|
2013-05-20 19:01:40 +08:00
|
|
|
#include "lsan.h"
|
|
|
|
#include "lsan_allocator.h"
|
2016-01-16 08:57:25 +08:00
|
|
|
#include "lsan_common.h"
|
2013-05-20 19:01:40 +08:00
|
|
|
#include "lsan_thread.h"
|
|
|
|
|
2017-01-31 15:15:37 +08:00
|
|
|
#include <stddef.h>
|
|
|
|
|
2013-05-20 19:01:40 +08:00
|
|
|
using namespace __lsan;
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
int pthread_attr_init(void *attr);
|
|
|
|
int pthread_attr_destroy(void *attr);
|
|
|
|
int pthread_attr_getdetachstate(void *attr, int *v);
|
|
|
|
int pthread_key_create(unsigned *key, void (*destructor)(void* v));
|
|
|
|
int pthread_setspecific(unsigned key, const void *v);
|
|
|
|
}
|
|
|
|
|
|
|
|
///// Malloc/free interceptors. /////
|
|
|
|
|
|
|
|
namespace std {
|
|
|
|
struct nothrow_t;
|
2017-08-17 02:09:29 +08:00
|
|
|
enum class align_val_t: size_t;
|
2013-05-20 19:01:40 +08:00
|
|
|
}
|
|
|
|
|
2017-04-12 04:05:02 +08:00
|
|
|
#if !SANITIZER_MAC
|
2013-05-20 19:01:40 +08:00
|
|
|
INTERCEPTOR(void*, malloc, uptr size) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2014-08-26 20:52:41 +08:00
|
|
|
GET_STACK_TRACE_MALLOC;
|
2017-04-12 04:05:02 +08:00
|
|
|
return lsan_malloc(size, stack);
|
2013-05-20 19:01:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(void, free, void *p) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2017-04-12 04:05:02 +08:00
|
|
|
lsan_free(p);
|
2013-05-20 19:01:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
|
2013-11-25 22:25:36 +08:00
|
|
|
if (lsan_init_is_running) {
|
|
|
|
// Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
|
|
|
|
const uptr kCallocPoolSize = 1024;
|
|
|
|
static uptr calloc_memory_for_dlsym[kCallocPoolSize];
|
|
|
|
static uptr allocated;
|
|
|
|
uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
|
|
|
|
void *mem = (void*)&calloc_memory_for_dlsym[allocated];
|
|
|
|
allocated += size_in_words;
|
|
|
|
CHECK(allocated < kCallocPoolSize);
|
|
|
|
return mem;
|
|
|
|
}
|
|
|
|
ENSURE_LSAN_INITED;
|
2014-08-26 20:52:41 +08:00
|
|
|
GET_STACK_TRACE_MALLOC;
|
2017-04-12 04:05:02 +08:00
|
|
|
return lsan_calloc(nmemb, size, stack);
|
2013-05-20 19:01:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(void*, realloc, void *q, uptr size) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2014-08-26 20:52:41 +08:00
|
|
|
GET_STACK_TRACE_MALLOC;
|
2017-04-12 04:05:02 +08:00
|
|
|
return lsan_realloc(q, size, stack);
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
|
|
|
|
ENSURE_LSAN_INITED;
|
|
|
|
GET_STACK_TRACE_MALLOC;
|
2018-03-13 05:59:06 +08:00
|
|
|
return lsan_posix_memalign(memptr, alignment, size, stack);
|
2013-05-20 19:01:40 +08:00
|
|
|
}
|
|
|
|
|
2017-04-12 04:05:02 +08:00
|
|
|
INTERCEPTOR(void*, valloc, uptr size) {
|
|
|
|
ENSURE_LSAN_INITED;
|
|
|
|
GET_STACK_TRACE_MALLOC;
|
|
|
|
return lsan_valloc(size, stack);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#if SANITIZER_INTERCEPT_MEMALIGN
|
2013-05-20 19:01:40 +08:00
|
|
|
INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2014-08-26 20:52:41 +08:00
|
|
|
GET_STACK_TRACE_MALLOC;
|
2017-04-12 04:05:02 +08:00
|
|
|
return lsan_memalign(alignment, size, stack);
|
2013-05-20 19:01:40 +08:00
|
|
|
}
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#define LSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
|
|
|
|
|
|
|
|
INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
|
|
|
|
ENSURE_LSAN_INITED;
|
|
|
|
GET_STACK_TRACE_MALLOC;
|
2017-04-12 04:05:02 +08:00
|
|
|
void *res = lsan_memalign(alignment, size, stack);
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
DTLS_on_libc_memalign(res, size);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
|
|
|
|
#else
|
|
|
|
#define LSAN_MAYBE_INTERCEPT_MEMALIGN
|
|
|
|
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
|
|
|
|
#endif // SANITIZER_INTERCEPT_MEMALIGN
|
2013-05-20 19:01:40 +08:00
|
|
|
|
2017-02-14 05:06:13 +08:00
|
|
|
#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
|
2014-07-04 15:30:34 +08:00
|
|
|
INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {
|
|
|
|
ENSURE_LSAN_INITED;
|
2014-08-26 20:52:41 +08:00
|
|
|
GET_STACK_TRACE_MALLOC;
|
2018-06-09 04:40:35 +08:00
|
|
|
return lsan_aligned_alloc(alignment, size, stack);
|
2014-07-04 15:30:34 +08:00
|
|
|
}
|
2017-02-14 05:06:13 +08:00
|
|
|
#define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
|
|
|
|
#else
|
|
|
|
#define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
|
|
|
|
#endif
|
2014-07-04 15:30:34 +08:00
|
|
|
|
2017-02-14 05:06:13 +08:00
|
|
|
#if SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE
|
2013-05-20 19:01:40 +08:00
|
|
|
INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2013-05-20 19:01:40 +08:00
|
|
|
return GetMallocUsableSize(ptr);
|
|
|
|
}
|
2017-02-14 05:06:13 +08:00
|
|
|
#define LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \
|
|
|
|
INTERCEPT_FUNCTION(malloc_usable_size)
|
|
|
|
#else
|
|
|
|
#define LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE
|
|
|
|
#endif
|
2013-05-20 19:01:40 +08:00
|
|
|
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
|
2013-05-20 19:01:40 +08:00
|
|
|
struct fake_mallinfo {
|
|
|
|
int x[10];
|
|
|
|
};
|
|
|
|
|
|
|
|
INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
|
|
|
|
struct fake_mallinfo res;
|
|
|
|
internal_memset(&res, 0, sizeof(res));
|
|
|
|
return res;
|
|
|
|
}
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
|
2013-05-20 19:01:40 +08:00
|
|
|
|
|
|
|
INTERCEPTOR(int, mallopt, int cmd, int value) {
|
|
|
|
return -1;
|
|
|
|
}
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#define LSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
|
|
|
|
#else
|
|
|
|
#define LSAN_MAYBE_INTERCEPT_MALLINFO
|
|
|
|
#define LSAN_MAYBE_INTERCEPT_MALLOPT
|
|
|
|
#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
|
2013-05-20 19:01:40 +08:00
|
|
|
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#if SANITIZER_INTERCEPT_PVALLOC
|
2013-06-25 22:05:52 +08:00
|
|
|
INTERCEPTOR(void*, pvalloc, uptr size) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2014-08-26 20:52:41 +08:00
|
|
|
GET_STACK_TRACE_MALLOC;
|
2013-06-25 22:05:52 +08:00
|
|
|
uptr PageSize = GetPageSizeCached();
|
|
|
|
size = RoundUpTo(size, PageSize);
|
|
|
|
if (size == 0) {
|
|
|
|
// pvalloc(0) should allocate one page.
|
|
|
|
size = PageSize;
|
|
|
|
}
|
|
|
|
return Allocate(stack, size, GetPageSizeCached(), kAlwaysClearMemory);
|
|
|
|
}
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#define LSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
|
|
|
|
#else
|
|
|
|
#define LSAN_MAYBE_INTERCEPT_PVALLOC
|
|
|
|
#endif // SANITIZER_INTERCEPT_PVALLOC
|
2013-06-25 22:05:52 +08:00
|
|
|
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#if SANITIZER_INTERCEPT_CFREE
|
2014-03-26 23:48:59 +08:00
|
|
|
INTERCEPTOR(void, cfree, void *p) ALIAS(WRAPPER_NAME(free));
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
#define LSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
|
|
|
|
#else
|
|
|
|
#define LSAN_MAYBE_INTERCEPT_CFREE
|
|
|
|
#endif // SANITIZER_INTERCEPT_CFREE
|
2013-06-25 22:05:52 +08:00
|
|
|
|
2017-05-03 15:09:10 +08:00
|
|
|
#if SANITIZER_INTERCEPT_MCHECK_MPROBE
|
|
|
|
INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, mprobe, void *ptr) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif // SANITIZER_INTERCEPT_MCHECK_MPROBE
|
|
|
|
|
2017-07-01 01:21:34 +08:00
|
|
|
|
2017-06-29 05:58:57 +08:00
|
|
|
// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
|
2018-06-06 02:02:09 +08:00
|
|
|
#define OPERATOR_NEW_BODY(nothrow)\
|
|
|
|
ENSURE_LSAN_INITED;\
|
|
|
|
GET_STACK_TRACE_MALLOC;\
|
|
|
|
void *res = lsan_malloc(size, stack);\
|
|
|
|
if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
|
2017-08-17 02:09:29 +08:00
|
|
|
return res;
|
2018-06-06 02:02:09 +08:00
|
|
|
#define OPERATOR_NEW_BODY_ALIGN(nothrow)\
|
|
|
|
ENSURE_LSAN_INITED;\
|
|
|
|
GET_STACK_TRACE_MALLOC;\
|
|
|
|
void *res = lsan_memalign((uptr)align, size, stack);\
|
|
|
|
if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
|
2017-06-29 05:58:57 +08:00
|
|
|
return res;
|
2013-06-25 22:05:52 +08:00
|
|
|
|
2018-06-06 02:02:09 +08:00
|
|
|
#define OPERATOR_DELETE_BODY\
|
|
|
|
ENSURE_LSAN_INITED;\
|
2017-08-17 02:09:29 +08:00
|
|
|
lsan_free(ptr);
|
2017-07-01 01:21:34 +08:00
|
|
|
|
|
|
|
// On OS X it's not enough to just provide our own 'operator new' and
|
|
|
|
// 'operator delete' implementations, because they're going to be in the runtime
|
|
|
|
// dylib, and the main executable will depend on both the runtime dylib and
|
|
|
|
// libstdc++, each of has its implementation of new and delete.
|
|
|
|
// To make sure that C++ allocation/deallocation operators are overridden on
|
|
|
|
// OS X we need to intercept them using their mangled names.
|
|
|
|
#if !SANITIZER_MAC
|
|
|
|
|
2013-06-25 22:05:52 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
2017-06-29 05:58:57 +08:00
|
|
|
void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
|
2013-06-25 22:05:52 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
2017-06-29 05:58:57 +08:00
|
|
|
void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
|
2013-06-25 22:05:52 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
2017-07-01 01:21:34 +08:00
|
|
|
void *operator new(size_t size, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_NEW_BODY(true /*nothrow*/); }
|
2013-06-25 22:05:52 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
2017-07-01 01:21:34 +08:00
|
|
|
void *operator new[](size_t size, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_NEW_BODY(true /*nothrow*/); }
|
2017-08-17 02:09:29 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void *operator new(size_t size, std::align_val_t align)
|
|
|
|
{ OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void *operator new[](size_t size, std::align_val_t align)
|
|
|
|
{ OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }
|
2013-06-25 22:05:52 +08:00
|
|
|
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
2015-08-10 23:24:22 +08:00
|
|
|
void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
|
2013-06-25 22:05:52 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
2015-08-10 23:24:22 +08:00
|
|
|
void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
|
2013-06-25 22:05:52 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
2017-07-01 01:21:34 +08:00
|
|
|
void operator delete[](void *ptr, std::nothrow_t const &)
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
2017-08-17 02:09:29 +08:00
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete(void *ptr, size_t size) NOEXCEPT
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete[](void *ptr, size_t size) NOEXCEPT
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete(void *ptr, std::align_val_t) NOEXCEPT
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete[](void *ptr, std::align_val_t) NOEXCEPT
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete(void *ptr, std::align_val_t, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete[](void *ptr, std::align_val_t, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete(void *ptr, size_t size, std::align_val_t) NOEXCEPT
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR_ATTRIBUTE
|
|
|
|
void operator delete[](void *ptr, size_t size, std::align_val_t) NOEXCEPT
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
2017-07-01 01:21:34 +08:00
|
|
|
|
|
|
|
#else // SANITIZER_MAC
|
|
|
|
|
|
|
|
INTERCEPTOR(void *, _Znwm, size_t size)
|
|
|
|
{ OPERATOR_NEW_BODY(false /*nothrow*/); }
|
|
|
|
INTERCEPTOR(void *, _Znam, size_t size)
|
|
|
|
{ OPERATOR_NEW_BODY(false /*nothrow*/); }
|
|
|
|
INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_NEW_BODY(true /*nothrow*/); }
|
|
|
|
INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_NEW_BODY(true /*nothrow*/); }
|
|
|
|
|
|
|
|
INTERCEPTOR(void, _ZdlPv, void *ptr)
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR(void, _ZdaPv, void *ptr)
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
|
|
|
|
{ OPERATOR_DELETE_BODY; }
|
|
|
|
|
|
|
|
#endif // !SANITIZER_MAC
|
|
|
|
|
2013-05-20 19:01:40 +08:00
|
|
|
|
|
|
|
///// Thread initialization and finalization. /////
|
|
|
|
|
2017-11-26 17:42:01 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2013-05-20 19:01:40 +08:00
|
|
|
static unsigned g_thread_finalize_key;
|
|
|
|
|
|
|
|
static void thread_finalize(void *v) {
|
|
|
|
uptr iter = (uptr)v;
|
|
|
|
if (iter > 1) {
|
|
|
|
if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) {
|
|
|
|
Report("LeakSanitizer: failed to set thread key.\n");
|
|
|
|
Die();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ThreadFinish();
|
|
|
|
}
|
2017-11-26 17:42:01 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if SANITIZER_NETBSD
|
|
|
|
INTERCEPTOR(void, _lwp_exit) {
|
|
|
|
ENSURE_LSAN_INITED;
|
|
|
|
ThreadFinish();
|
|
|
|
REAL(_lwp_exit)();
|
|
|
|
}
|
|
|
|
#define LSAN_MAYBE_INTERCEPT__LWP_EXIT INTERCEPT_FUNCTION(_lwp_exit)
|
|
|
|
#else
|
|
|
|
#define LSAN_MAYBE_INTERCEPT__LWP_EXIT
|
|
|
|
#endif
|
2013-05-20 19:01:40 +08:00
|
|
|
|
|
|
|
struct ThreadParam {
|
|
|
|
void *(*callback)(void *arg);
|
|
|
|
void *param;
|
|
|
|
atomic_uintptr_t tid;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern "C" void *__lsan_thread_start_func(void *arg) {
|
|
|
|
ThreadParam *p = (ThreadParam*)arg;
|
|
|
|
void* (*callback)(void *arg) = p->callback;
|
|
|
|
void *param = p->param;
|
|
|
|
// Wait until the last iteration to maximize the chance that we are the last
|
|
|
|
// destructor to run.
|
2017-11-26 17:42:01 +08:00
|
|
|
#if !SANITIZER_NETBSD
|
2013-05-20 19:01:40 +08:00
|
|
|
if (pthread_setspecific(g_thread_finalize_key,
|
2015-06-30 04:28:55 +08:00
|
|
|
(void*)GetPthreadDestructorIterations())) {
|
2013-05-20 19:01:40 +08:00
|
|
|
Report("LeakSanitizer: failed to set thread key.\n");
|
|
|
|
Die();
|
|
|
|
}
|
2017-11-26 17:42:01 +08:00
|
|
|
#endif
|
2013-05-20 19:01:40 +08:00
|
|
|
int tid = 0;
|
|
|
|
while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0)
|
|
|
|
internal_sched_yield();
|
|
|
|
SetCurrentThread(tid);
|
|
|
|
ThreadStart(tid, GetTid());
|
2014-12-05 08:10:15 +08:00
|
|
|
atomic_store(&p->tid, 0, memory_order_release);
|
2013-05-20 19:01:40 +08:00
|
|
|
return callback(param);
|
|
|
|
}
|
|
|
|
|
2013-05-23 18:24:44 +08:00
|
|
|
INTERCEPTOR(int, pthread_create, void *th, void *attr,
|
|
|
|
void *(*callback)(void *), void *param) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2013-07-08 20:57:24 +08:00
|
|
|
EnsureMainThreadIDIsCorrect();
|
2013-05-20 19:01:40 +08:00
|
|
|
__sanitizer_pthread_attr_t myattr;
|
2015-10-01 08:22:21 +08:00
|
|
|
if (!attr) {
|
2013-05-20 19:01:40 +08:00
|
|
|
pthread_attr_init(&myattr);
|
|
|
|
attr = &myattr;
|
|
|
|
}
|
2014-02-24 16:53:26 +08:00
|
|
|
AdjustStackSize(attr);
|
2013-05-20 19:01:40 +08:00
|
|
|
int detached = 0;
|
|
|
|
pthread_attr_getdetachstate(attr, &detached);
|
|
|
|
ThreadParam p;
|
|
|
|
p.callback = callback;
|
|
|
|
p.param = param;
|
|
|
|
atomic_store(&p.tid, 0, memory_order_relaxed);
|
2016-01-16 08:57:25 +08:00
|
|
|
int res;
|
|
|
|
{
|
|
|
|
// Ignore all allocations made by pthread_create: thread stack/TLS may be
|
|
|
|
// stored by pthread for future reuse even after thread destruction, and
|
|
|
|
// the linked list it's stored in doesn't even hold valid pointers to the
|
|
|
|
// objects, the latter are calculated by obscure pointer arithmetic.
|
|
|
|
ScopedInterceptorDisabler disabler;
|
|
|
|
res = REAL(pthread_create)(th, attr, __lsan_thread_start_func, &p);
|
|
|
|
}
|
2013-05-20 19:01:40 +08:00
|
|
|
if (res == 0) {
|
2017-04-14 01:28:52 +08:00
|
|
|
int tid = ThreadCreate(GetCurrentThread(), *(uptr *)th,
|
|
|
|
IsStateDetached(detached));
|
2013-05-20 19:01:40 +08:00
|
|
|
CHECK_NE(tid, 0);
|
|
|
|
atomic_store(&p.tid, tid, memory_order_release);
|
|
|
|
while (atomic_load(&p.tid, memory_order_acquire) != 0)
|
|
|
|
internal_sched_yield();
|
|
|
|
}
|
|
|
|
if (attr == &myattr)
|
|
|
|
pthread_attr_destroy(&myattr);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
INTERCEPTOR(int, pthread_join, void *th, void **ret) {
|
2013-11-25 22:25:36 +08:00
|
|
|
ENSURE_LSAN_INITED;
|
2013-05-20 19:01:40 +08:00
|
|
|
int tid = ThreadTid((uptr)th);
|
|
|
|
int res = REAL(pthread_join)(th, ret);
|
|
|
|
if (res == 0)
|
|
|
|
ThreadJoin(tid);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Don't call exit() from atexit handlers on Darwin
Summary:
Calling exit() from an atexit handler is undefined behavior.
On Linux, it's unavoidable, since we cannot intercept exit (_exit isn't called
if a user program uses return instead of exit()), and I haven't
seen it cause issues regardless.
However, on Darwin, I have a fairly complex internal test that hangs roughly
once in every 300 runs after leak reporting finishes, which is resolved with
this patch, and is presumably due to the undefined behavior (since the Die() is
the only thing that happens after the end of leak reporting).
In addition, this is the way TSan works as well, where an atexit handler+Die()
is used on Linux, and an _exit() interceptor is used on Darwin. I'm not sure if it's
intentionally structured that way in TSan, since TSan sets up the atexit handler and the
_exit() interceptor on both platforms, but I have observed that on Darwin, only the
_exit() interceptor is used, and on Linux the atexit handler is used.
There is some additional related discussion here: https://reviews.llvm.org/D35085
Reviewers: alekseyshl, kubamracek
Subscribers: eugenis, vsk, llvm-commits
Differential Revision: https://reviews.llvm.org/D35513
llvm-svn: 308353
2017-07-19 04:18:32 +08:00
|
|
|
INTERCEPTOR(void, _exit, int status) {
|
|
|
|
if (status == 0 && HasReportedLeaks()) status = common_flags()->exitcode;
|
|
|
|
REAL(_exit)(status);
|
|
|
|
}
|
|
|
|
|
2017-09-23 06:57:48 +08:00
|
|
|
#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
|
|
|
|
#include "sanitizer_common/sanitizer_signal_interceptors.inc"
|
|
|
|
|
2013-05-20 19:01:40 +08:00
|
|
|
namespace __lsan {
|
|
|
|
|
|
|
|
void InitializeInterceptors() {
|
2017-09-23 06:57:48 +08:00
|
|
|
InitializeSignalInterceptors();
|
|
|
|
|
2013-05-20 19:01:40 +08:00
|
|
|
INTERCEPT_FUNCTION(malloc);
|
|
|
|
INTERCEPT_FUNCTION(free);
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
LSAN_MAYBE_INTERCEPT_CFREE;
|
2013-05-20 19:01:40 +08:00
|
|
|
INTERCEPT_FUNCTION(calloc);
|
|
|
|
INTERCEPT_FUNCTION(realloc);
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
LSAN_MAYBE_INTERCEPT_MEMALIGN;
|
|
|
|
LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
|
2017-02-14 05:06:13 +08:00
|
|
|
LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;
|
2013-05-20 19:01:40 +08:00
|
|
|
INTERCEPT_FUNCTION(posix_memalign);
|
|
|
|
INTERCEPT_FUNCTION(valloc);
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
LSAN_MAYBE_INTERCEPT_PVALLOC;
|
2017-02-14 05:06:13 +08:00
|
|
|
LSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;
|
Recommit: Stop intercepting some malloc-related functions on FreeBSD and
macOS
Summary:
In https://bugs.freebsd.org/215125 I was notified that some configure
scripts attempt to test for the Linux-specific `mallinfo` and `mallopt`
functions by compiling and linking small programs which references the
functions, and observing whether that results in errors.
FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so
normally these tests would fail, but when sanitizers are enabled, they
incorrectly succeed, because the sanitizers define interceptors for
these functions. This also applies to some other malloc-related
functions, such as `memalign`, `pvalloc` and `cfree`.
Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`,
`pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers.
Also delete the non-functional `cfree` wrapper for Windows, to fix the
test cases on that platform.
Reviewers: emaste, kcc, rnk
Subscribers: timurrrr, eugenis, hans, joerg, llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D27654
llvm-svn: 293536
2017-01-31 03:06:13 +08:00
|
|
|
LSAN_MAYBE_INTERCEPT_MALLINFO;
|
|
|
|
LSAN_MAYBE_INTERCEPT_MALLOPT;
|
2013-05-20 19:01:40 +08:00
|
|
|
INTERCEPT_FUNCTION(pthread_create);
|
|
|
|
INTERCEPT_FUNCTION(pthread_join);
|
Don't call exit() from atexit handlers on Darwin
Summary:
Calling exit() from an atexit handler is undefined behavior.
On Linux, it's unavoidable, since we cannot intercept exit (_exit isn't called
if a user program uses return instead of exit()), and I haven't
seen it cause issues regardless.
However, on Darwin, I have a fairly complex internal test that hangs roughly
once in every 300 runs after leak reporting finishes, which is resolved with
this patch, and is presumably due to the undefined behavior (since the Die() is
the only thing that happens after the end of leak reporting).
In addition, this is the way TSan works as well, where an atexit handler+Die()
is used on Linux, and an _exit() interceptor is used on Darwin. I'm not sure if it's
intentionally structured that way in TSan, since TSan sets up the atexit handler and the
_exit() interceptor on both platforms, but I have observed that on Darwin, only the
_exit() interceptor is used, and on Linux the atexit handler is used.
There is some additional related discussion here: https://reviews.llvm.org/D35085
Reviewers: alekseyshl, kubamracek
Subscribers: eugenis, vsk, llvm-commits
Differential Revision: https://reviews.llvm.org/D35513
llvm-svn: 308353
2017-07-19 04:18:32 +08:00
|
|
|
INTERCEPT_FUNCTION(_exit);
|
2013-05-20 19:01:40 +08:00
|
|
|
|
2017-11-26 17:42:01 +08:00
|
|
|
LSAN_MAYBE_INTERCEPT__LWP_EXIT;
|
|
|
|
|
|
|
|
#if !SANITIZER_NETBSD
|
2013-05-20 19:01:40 +08:00
|
|
|
if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
|
|
|
|
Report("LeakSanitizer: failed to create thread key.\n");
|
|
|
|
Die();
|
|
|
|
}
|
2017-11-26 17:42:01 +08:00
|
|
|
#endif
|
2013-05-20 19:01:40 +08:00
|
|
|
}
|
|
|
|
|
2015-10-01 08:22:21 +08:00
|
|
|
} // namespace __lsan
|