mfbt/MemoryChecking.h
author James Graham <james@hoppipolla.co.uk>
Mon, 21 May 2018 11:37:35 +0100
changeset 1555220 4c1f3fe87bc0049ab9f4138994d3c10d1e4a8514
parent 283493 e0804520017751586459e0542e2b392a1b74bd49
child 284869 6f0ee96e21adcf5f5077a346b63637b07e6ff41d
child 316347 a87815b36ee9bc0239635c65fc97e89947cb9519
child 316441 df0bf10ed913e541d4cf046544263768588ce88b
child 686686 3b3714a5916b37416a38d9eed40d54e0f99052e3
child 712721 0b28818a4d9b65f7093b2a8af01e4fc5398f5683
child 1049334 cbb8fdf1daf98a15f7d57f6b08d273bdf96aa1a0
child 1078460 fa5693c44aee0d572aa0594539b79deab2db9c5d
child 1336492 46ef8bf6c68664b27953e4680747da7a985c30b2
child 1343097 98e2b4ee9775a2a2b5cc1bb8a390bfe901814f38
child 1657331 59a761123310b8d7366a634922ee23887f34f8f8
child 1658304 307cb70a2b316693571c46e0f434af395d12c99e
child 1658306 aed9cae526b0553fdca8d3e17af29b13f8b2e3f0
child 1658321 c4a3ed98c39293ab38438933db1c4844782db1dd
permissions -rw-r--r--
Bug 1354232 - Add support for LSAN to mozlog, r=ahal, mccr8 This adds two new actions to mozlog, one for reporting an LSAN failure, and one for reporting the summary. MozReview-Commit-ID: D7ep27SrI1n

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Provides a common interface to the ASan (AddressSanitizer) and Valgrind
 * functions used to mark memory in certain ways. In detail, the following
 * three macros are provided:
 *
 *   MOZ_MAKE_MEM_NOACCESS  - Mark memory as unsafe to access (e.g. freed)
 *   MOZ_MAKE_MEM_UNDEFINED - Mark memory as accessible, with content undefined
 *   MOZ_MAKE_MEM_DEFINED - Mark memory as accessible, with content defined
 *
 * With Valgrind in use, these directly map to the three respective Valgrind
 * macros. With ASan in use, the NOACCESS macro maps to poisoning the memory,
 * while the UNDEFINED/DEFINED macros unpoison memory.
 *
 * With no memory checker available, all macros expand to the empty statement.
 */

#ifndef mozilla_MemoryChecking_h
#define mozilla_MemoryChecking_h

#if defined(MOZ_VALGRIND)
#include "valgrind/memcheck.h"
#endif

#if defined(MOZ_ASAN) || defined(MOZ_VALGRIND)
#define MOZ_HAVE_MEM_CHECKS 1
#endif

#if defined(MOZ_ASAN)
#include <stddef.h>

#include "mozilla/Attributes.h"
#include "mozilla/Types.h"

#ifdef _MSC_VER
// In clang-cl based ASAN, we link against the memory poisoning functions
// statically.
#define MOZ_ASAN_VISIBILITY
#else
#define MOZ_ASAN_VISIBILITY MOZ_EXPORT
#endif

extern "C" {
/* These definitions are usually provided through the
 * sanitizer/asan_interface.h header installed by ASan.
 */
void MOZ_ASAN_VISIBILITY
__asan_poison_memory_region(void const volatile *addr, size_t size);
void MOZ_ASAN_VISIBILITY
__asan_unpoison_memory_region(void const volatile *addr, size_t size);

#define MOZ_MAKE_MEM_NOACCESS(addr, size) \
  __asan_poison_memory_region((addr), (size))

#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \
  __asan_unpoison_memory_region((addr), (size))

#define MOZ_MAKE_MEM_DEFINED(addr, size) \
  __asan_unpoison_memory_region((addr), (size))

/*
 * These definitions are usually provided through the
 * sanitizer/lsan_interface.h header installed by LSan.
 */
void MOZ_EXPORT
__lsan_ignore_object(const void *p);

}
#elif defined(MOZ_MSAN)
#include <stddef.h>

#include "mozilla/Types.h"

extern "C" {
/* These definitions are usually provided through the
 * sanitizer/msan_interface.h header installed by MSan.
 */
void MOZ_EXPORT
__msan_poison(void const volatile *addr, size_t size);
void MOZ_EXPORT
__msan_unpoison(void const volatile *addr, size_t size);

#define MOZ_MAKE_MEM_NOACCESS(addr, size) \
  __msan_poison((addr), (size))

#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \
  __msan_poison((addr), (size))

#define MOZ_MAKE_MEM_DEFINED(addr, size) \
  __msan_unpoison((addr), (size))
}
#elif defined(MOZ_VALGRIND)
#define MOZ_MAKE_MEM_NOACCESS(addr, size) \
  VALGRIND_MAKE_MEM_NOACCESS((addr), (size))

#define MOZ_MAKE_MEM_UNDEFINED(addr, size) \
  VALGRIND_MAKE_MEM_UNDEFINED((addr), (size))

#define MOZ_MAKE_MEM_DEFINED(addr, size) \
  VALGRIND_MAKE_MEM_DEFINED((addr), (size))
#else

#define MOZ_MAKE_MEM_NOACCESS(addr, size) do {} while (0)
#define MOZ_MAKE_MEM_UNDEFINED(addr, size) do {} while (0)
#define MOZ_MAKE_MEM_DEFINED(addr, size) do {} while (0)

#endif

/*
 * MOZ_LSAN_INTENTIONAL_LEAK(X) is a macro to tell LeakSanitizer that X
 * points to a value that will intentionally never be deallocated during
 * the execution of the process.
 *
 * Additional uses of this macro should be reviewed by people
 * conversant in leak-checking and/or MFBT peers.
 */
#if defined(MOZ_ASAN)
#  define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) __lsan_ignore_object(X)
#else
#  define MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(X) /* nothing */
#endif // defined(MOZ_ASAN)


#endif /* mozilla_MemoryChecking_h */