This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libsanitizer merge from upstream r208536


On Thu, May 22, 2014 at 3:43 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, May 22, 2014 at 01:03:48PM +0200, Jakub Jelinek wrote:
>> There are various other changes to asan_test.cc, so guess some work is needed on that.
>
> Ok, tried to merge also g++.dg/asan from the same revision as you've merged
> libsanitizer.
Oh, cool.

>
> On x86_64-linux, both -m32 and -m64 I see
> FAIL: g++.dg/asan/asan_test.C  -O2  AddressSanitizer_UAF_Packed5 p[0] = p[3] execution test
> FAIL: g++.dg/asan/asan_test.C  -O2  AddressSanitizer_UAF_Packed5 p[3] = p[0] execution test
> and with -m32 additionally:
> FAIL: g++.dg/asan/asan_test.C  -O2  AddressSanitizer_UAF_long_double Ident(p)[12] = 0 execution test
> FAIL: g++.dg/asan/asan_test.C  -O2  AddressSanitizer_UAF_long_double Ident(p)[0] = Ident(p)[12] execution test
> The former boils down into:
> struct Packed5 {
>   int x;
>   char c;
> } __attribute__((packed));
>
> int
> main ()
> {
>   Packed5 *p = new Packed5[2];
>   asm volatile ("" : "+r" (p));
>   p[0] = p[3];
>   p[3] = p[0];
>   return 0;
> }
>
> Right now we instrument only accesses which have sizes power of two
> <= 16:
>
>   size_in_bytes = int_size_in_bytes (type);
>   if ((size_in_bytes & (size_in_bytes - 1)) != 0
>       || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16)
>     return;
>
> I thought so did LLVM, has that changed recently?

Not really recently... (Feb 2013)
http://llvm.org/viewvc/llvm-project?rev=175507&view=rev

--kcc

>
> 2014-05-22  Jakub Jelinek  <jakub@redhat.com>
>
>         * g++.dg/asan/asan_test.C: Add -std=c++11 and
>         -DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options, remove
>         -DASAN_USE_DEJAGNU_GTEST=1.
>         * g++.dg/asan/asan_mem_test.cc: Updated from upstream
>         r209283.
>         * g++.dg/asan/asan_oob_test.cc: Likewise.
>         * g++.dg/asan/sanitizer_test_utils.h: Likewise.
>         * g++.dg/asan/asan_str_test.cc: Likewise.
>         * g++.dg/asan/asan_test_utils.h: Likewise.
>         * g++.dg/asan/sanitizer_test_config.h: Likewise.
>         * g++.dg/asan/asan_test.cc: Likewise.
>         * g++.dg/asan/sanitizer_pthread_wrappers.h: New file.
>         Imported from upstream r209283.
>         * g++.dg/asan/asan_test_config.h: Likewise.
>
> --- gcc/testsuite/g++.dg/asan/asan_test.C.jj    2013-02-14 09:38:05.000000000 +0100
> +++ gcc/testsuite/g++.dg/asan/asan_test.C       2014-05-22 13:22:33.747459933 +0200
> @@ -2,7 +2,7 @@
>  // { dg-skip-if "" { *-*-* } { "*" } { "-O2" } }
>  // { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
>  // { dg-additional-sources "asan_globals_test-wrapper.cc" }
> -// { dg-options "-fsanitize=address -fno-builtin -Wall -Wno-format -Werror -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DASAN_USE_DEJAGNU_GTEST=1 -lasan -lpthread -ldl" }
> +// { dg-options "-std=c++11 -fsanitize=address -fno-builtin -Wall -Wno-format -Werror -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DSANITIZER_USE_DEJAGNU_GTEST=1 -lasan -lpthread -ldl" }
>  // { dg-additional-options "-DASAN_NEEDS_SEGV=1" { target { ! arm*-*-* } } }
>  // { dg-additional-options "-DASAN_LOW_MEMORY=1 -DASAN_NEEDS_SEGV=0" { target arm*-*-* } }
>  // { dg-additional-options "-DASAN_AVOID_EXPENSIVE_TESTS=1" { target { ! run_expensive_tests } } }
> --- gcc/testsuite/g++.dg/asan/asan_mem_test.cc.jj       2013-02-14 09:38:05.697773648 +0100
> +++ gcc/testsuite/g++.dg/asan/asan_mem_test.cc  2014-05-22 13:13:48.158014955 +0200
> @@ -74,17 +74,17 @@ TEST(AddressSanitizer, MemSetOOBTest) {
>  // Strictly speaking we are not guaranteed to find such two pointers,
>  // but given the structure of asan's allocator we will.
>  static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
> -  vector<char *> v;
> +  vector<uintptr_t> v;
>    bool res = false;
>    for (size_t i = 0; i < 1000U && !res; i++) {
> -    v.push_back(new char[size]);
> +    v.push_back(reinterpret_cast<uintptr_t>(new char[size]));
>      if (i == 0) continue;
>      sort(v.begin(), v.end());
>      for (size_t j = 1; j < v.size(); j++) {
>        assert(v[j] > v[j-1]);
>        if ((size_t)(v[j] - v[j-1]) < size * 2) {
> -        *x2 = v[j];
> -        *x1 = v[j-1];
> +        *x2 = reinterpret_cast<char*>(v[j]);
> +        *x1 = reinterpret_cast<char*>(v[j-1]);
>          res = true;
>          break;
>        }
> @@ -92,9 +92,10 @@ static bool AllocateTwoAdjacentArrays(ch
>    }
>
>    for (size_t i = 0; i < v.size(); i++) {
> -    if (res && v[i] == *x1) continue;
> -    if (res && v[i] == *x2) continue;
> -    delete [] v[i];
> +    char *p = reinterpret_cast<char *>(v[i]);
> +    if (res && p == *x1) continue;
> +    if (res && p == *x2) continue;
> +    delete [] p;
>    }
>    return res;
>  }
> @@ -223,6 +224,13 @@ TEST(AddressSanitizer, MemCmpOOBTest) {
>    s1[size - 1] = '\0';
>    s2[size - 1] = '\0';
>    EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
> +
> +  // Even if the buffers differ in the first byte, we still assume that
> +  // memcmp may access the whole buffer and thus reporting the overflow here:
> +  s1[0] = 1;
> +  s2[0] = 123;
> +  EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
> +
>    free(s1);
>    free(s2);
>  }
> --- gcc/testsuite/g++.dg/asan/asan_oob_test.cc.jj       2013-02-14 09:38:05.697773648 +0100
> +++ gcc/testsuite/g++.dg/asan/asan_oob_test.cc  2014-05-22 13:13:49.976009670 +0200
> @@ -97,7 +97,6 @@ TEST(AddressSanitizer, OOBRightTest) {
>    }
>  }
>
> -#if ASAN_ALLOCATOR_VERSION == 2  // Broken with the asan_allocator1
>  TEST(AddressSanitizer, LargeOOBRightTest) {
>    size_t large_power_of_two = 1 << 19;
>    for (size_t i = 16; i <= 256; i *= 2) {
> @@ -107,7 +106,6 @@ TEST(AddressSanitizer, LargeOOBRightTest
>      delete [] p;
>    }
>  }
> -#endif  // ASAN_ALLOCATOR_VERSION == 2
>
>  TEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) {
>    oob_test<U1>(10, -1);
> --- gcc/testsuite/g++.dg/asan/sanitizer_test_utils.h.jj 2013-02-28 22:22:03.000000000 +0100
> +++ gcc/testsuite/g++.dg/asan/sanitizer_test_utils.h    2014-05-22 13:10:27.781920740 +0200
> @@ -14,32 +14,47 @@
>  #define SANITIZER_TEST_UTILS_H
>
>  #if defined(_WIN32)
> -typedef unsigned __int8  uint8_t;
> -typedef unsigned __int16 uint16_t;
> -typedef unsigned __int32 uint32_t;
> -typedef unsigned __int64 uint64_t;
> -typedef __int8           int8_t;
> -typedef __int16          int16_t;
> -typedef __int32          int32_t;
> -typedef __int64          int64_t;
> +// <windows.h> should always be the first include on Windows.
> +# include <windows.h>
> +// MSVS headers define max/min as macros, so std::max/min gets crazy.
> +# undef max
> +# undef min
> +#endif
> +
> +#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
> +# define INCLUDED_FROM_SANITIZER_TEST_UTILS_H
> +# include "sanitizer_test_config.h"
> +# undef INCLUDED_FROM_SANITIZER_TEST_UTILS_H
> +#endif
> +
> +#include <stdint.h>
> +
> +#if defined(_MSC_VER)
>  # define NOINLINE __declspec(noinline)
> -# define USED
> -#else  // defined(_WIN32)
> +#else  // defined(_MSC_VER)
>  # define NOINLINE __attribute__((noinline))
> +#endif  // defined(_MSC_VER)
> +
> +#if !defined(_MSC_VER) || defined(__clang__)
> +# define UNUSED __attribute__((unused))
>  # define USED __attribute__((used))
> -#include <stdint.h>
> -#endif  // defined(_WIN32)
> +#else
> +# define UNUSED
> +# define USED
> +#endif
>
>  #if !defined(__has_feature)
>  #define __has_feature(x) 0
>  #endif
>
> -#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
> -# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \
> +#ifndef ATTRIBUTE_NO_SANITIZE_ADDRESS
> +# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
> +#  define ATTRIBUTE_NO_SANITIZE_ADDRESS \
>      __attribute__((no_sanitize_address))
> -#else
> -# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
> -#endif
> +# else
> +#  define ATTRIBUTE_NO_SANITIZE_ADDRESS
> +# endif
> +#endif  // ATTRIBUTE_NO_SANITIZE_ADDRESS
>
>  #if __LP64__ || defined(_WIN64)
>  #  define SANITIZER_WORDSIZE 64
> @@ -49,7 +64,9 @@ typedef __int64          int64_t;
>
>  // Make the compiler thinks that something is going on there.
>  inline void break_optimization(void *arg) {
> +#if !defined(_WIN32) || defined(__clang__)
>    __asm__ __volatile__("" : : "r" (arg) : "memory");
> +#endif
>  }
>
>  // This function returns its parameter but in such a way that compiler
> @@ -74,5 +91,28 @@ static inline uint32_t my_rand() {
>    return my_rand_r(&global_seed);
>  }
>
> +// Set availability of platform-specific functions.
> +
> +#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__) && !defined(_WIN32)
> +# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 1
> +#else
> +# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 0
> +#endif
> +
> +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(_WIN32)
> +# define SANITIZER_TEST_HAS_MEMALIGN 1
> +# define SANITIZER_TEST_HAS_PVALLOC 1
> +# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 1
> +#else
> +# define SANITIZER_TEST_HAS_MEMALIGN 0
> +# define SANITIZER_TEST_HAS_PVALLOC 0
> +# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 0
> +#endif
> +
> +#if !defined(__APPLE__)
> +# define SANITIZER_TEST_HAS_STRNLEN 1
> +#else
> +# define SANITIZER_TEST_HAS_STRNLEN 0
> +#endif
>
>  #endif  // SANITIZER_TEST_UTILS_H
> --- gcc/testsuite/g++.dg/asan/asan_test_config.h.jj     2012-12-03 12:44:28.983724406 +0100
> +++ gcc/testsuite/g++.dg/asan/asan_test_config.h        2014-05-22 13:13:53.392991725 +0200
> @@ -19,12 +19,6 @@
>  #include <string>
>  #include <map>
>
> -#if ASAN_USE_DEJAGNU_GTEST
> -# include "dejagnu-gtest.h"
> -#else
> -# include "gtest/gtest.h"
> -#endif
> -
>  using std::string;
>  using std::vector;
>  using std::map;
> @@ -42,11 +36,11 @@ using std::map;
>  #endif
>
>  #ifndef ASAN_NEEDS_SEGV
> -# error "please define ASAN_NEEDS_SEGV"
> -#endif
> -
> -#ifndef ASAN_LOW_MEMORY
> -# define ASAN_LOW_MEMORY 0
> +# if defined(_WIN32)
> +#  define ASAN_NEEDS_SEGV 0
> +# else
> +#  define ASAN_NEEDS_SEGV 1
> +# endif
>  #endif
>
>  #ifndef ASAN_AVOID_EXPENSIVE_TESTS
> --- gcc/testsuite/g++.dg/asan/asan_str_test.cc.jj       2013-02-14 09:38:05.697773648 +0100
> +++ gcc/testsuite/g++.dg/asan/asan_str_test.cc  2014-05-22 13:13:51.694002758 +0200
> @@ -10,6 +10,10 @@
>  //===----------------------------------------------------------------------===//
>  #include "asan_test_utils.h"
>
> +#if defined(__APPLE__)
> +#include <AvailabilityMacros.h>  // For MAC_OS_X_VERSION_*
> +#endif
> +
>  // Used for string functions tests
>  static char global_string[] = "global";
>  static size_t global_string_length = 6;
> @@ -59,7 +63,19 @@ TEST(AddressSanitizer, StrLenOOBTest) {
>    free(heap_string);
>  }
>
> -#ifndef __APPLE__
> +TEST(AddressSanitizer, WcsLenTest) {
> +  EXPECT_EQ(0U, wcslen(Ident(L"")));
> +  size_t hello_len = 13;
> +  size_t hello_size = (hello_len + 1) * sizeof(wchar_t);
> +  EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!")));
> +  wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size));
> +  memcpy(heap_string, L"Hello, World!", hello_size);
> +  EXPECT_EQ(hello_len, Ident(wcslen(heap_string)));
> +  EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0));
> +  free(heap_string);
> +}
> +
> +#if SANITIZER_TEST_HAS_STRNLEN
>  TEST(AddressSanitizer, StrNLenOOBTest) {
>    size_t size = Ident(123);
>    char *str = MallocAndMemsetString(size);
> @@ -77,7 +93,7 @@ TEST(AddressSanitizer, StrNLenOOBTest) {
>    EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
>    free(str);
>  }
> -#endif
> +#endif  // SANITIZER_TEST_HAS_STRNLEN
>
>  TEST(AddressSanitizer, StrDupOOBTest) {
>    size_t size = Ident(42);
> @@ -168,7 +184,7 @@ TEST(AddressSanitizer, StrNCpyOOBTest) {
>  typedef char*(*PointerToStrChr1)(const char*, int);
>  typedef char*(*PointerToStrChr2)(char*, int);
>
> -USED static void RunStrChrTest(PointerToStrChr1 StrChr) {
> +UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) {
>    size_t size = Ident(100);
>    char *str = MallocAndMemsetString(size);
>    str[10] = 'q';
> @@ -184,7 +200,7 @@ USED static void RunStrChrTest(PointerTo
>    EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
>    free(str);
>  }
> -USED static void RunStrChrTest(PointerToStrChr2 StrChr) {
> +UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) {
>    size_t size = Ident(100);
>    char *str = MallocAndMemsetString(size);
>    str[10] = 'q';
> @@ -203,7 +219,9 @@ USED static void RunStrChrTest(PointerTo
>
>  TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
>    RunStrChrTest(&strchr);
> +#if !defined(_WIN32)  // no index() on Windows.
>    RunStrChrTest(&index);
> +#endif
>  }
>
>  TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
> @@ -226,6 +244,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsL
>    EXPECT_LT(0, strncmp("baa", "aaa", 1));
>    EXPECT_LT(0, strncmp("zyx", "", 2));
>
> +#if !defined(_WIN32)  // no str[n]casecmp on Windows.
>    // strcasecmp
>    EXPECT_EQ(0, strcasecmp("", ""));
>    EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
> @@ -245,6 +264,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsL
>    EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
>    EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
>    EXPECT_LT(0, strncasecmp("zyx", "", 2));
> +#endif
>
>    // memcmp
>    EXPECT_EQ(0, memcmp("a", "b", 0));
> @@ -287,9 +307,11 @@ TEST(AddressSanitizer, StrCmpOOBTest) {
>    RunStrCmpTest(&strcmp);
>  }
>
> +#if !defined(_WIN32)  // no str[n]casecmp on Windows.
>  TEST(AddressSanitizer, StrCaseCmpOOBTest) {
>    RunStrCmpTest(&strcasecmp);
>  }
> +#endif
>
>  typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
>  void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
> @@ -322,9 +344,12 @@ TEST(AddressSanitizer, StrNCmpOOBTest) {
>    RunStrNCmpTest(&strncmp);
>  }
>
> +#if !defined(_WIN32)  // no str[n]casecmp on Windows.
>  TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
>    RunStrNCmpTest(&strncasecmp);
>  }
> +#endif
> +
>  TEST(AddressSanitizer, StrCatOOBTest) {
>    // strcat() reads strlen(to) bytes from |to| before concatenating.
>    size_t to_size = Ident(100);
> @@ -506,11 +531,13 @@ void RunAtoiOOBTest(PointerToCallAtoi At
>    free(array);
>  }
>
> +#if !defined(_WIN32)  // FIXME: Fix and enable on Windows.
>  TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
>    RunAtoiOOBTest(&CallAtoi);
>    RunAtoiOOBTest(&CallAtol);
>    RunAtoiOOBTest(&CallAtoll);
>  }
> +#endif
>
>  void CallStrtol(const char *nptr, char **endptr, int base) {
>    Ident(strtol(nptr, endptr, base));
> @@ -560,11 +587,13 @@ void RunStrtolOOBTest(PointerToCallStrto
>    free(array);
>  }
>
> +#if !defined(_WIN32)  // FIXME: Fix and enable on Windows.
>  TEST(AddressSanitizer, StrtollOOBTest) {
>    RunStrtolOOBTest(&CallStrtoll);
>  }
>  TEST(AddressSanitizer, StrtolOOBTest) {
>    RunStrtolOOBTest(&CallStrtol);
>  }
> +#endif
>
>
> --- gcc/testsuite/g++.dg/asan/asan_test_utils.h.jj      2013-02-14 09:38:05.688773689 +0100
> +++ gcc/testsuite/g++.dg/asan/asan_test_utils.h 2014-05-22 13:13:55.087985295 +0200
> @@ -12,24 +12,28 @@
>  #ifndef ASAN_TEST_UTILS_H
>  #define ASAN_TEST_UTILS_H
>
> -#if !defined(ASAN_EXTERNAL_TEST_CONFIG)
> +#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
>  # define INCLUDED_FROM_ASAN_TEST_UTILS_H
>  # include "asan_test_config.h"
>  # undef INCLUDED_FROM_ASAN_TEST_UTILS_H
>  #endif
>
>  #include "sanitizer_test_utils.h"
> +#include "sanitizer_pthread_wrappers.h"
> +
>  #include <stdio.h>
>  #include <signal.h>
>  #include <stdlib.h>
>  #include <string.h>
> -#include <strings.h>
> -#include <pthread.h>
>  #include <stdint.h>
> -#include <setjmp.h>
>  #include <assert.h>
>  #include <algorithm>
> -#include <sys/mman.h>
> +
> +#if !defined(_WIN32)
> +# include <strings.h>
> +# include <sys/mman.h>
> +# include <setjmp.h>
> +#endif
>
>  #ifdef __linux__
>  # include <sys/prctl.h>
> @@ -39,18 +43,10 @@
>  #include <unistd.h>
>  #endif
>
> -#if defined(__i386__) || defined(__x86_64__)
> -#include <emmintrin.h>
> -#endif
> -
> -#ifndef __APPLE__
> +#if !defined(__APPLE__) && !defined(__FreeBSD__)
>  #include <malloc.h>
>  #endif
>
> -// Check that pthread_create/pthread_join return success.
> -#define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))
> -#define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))
> -
>  #if ASAN_HAS_EXCEPTIONS
>  # define ASAN_THROW(x) throw (x)
>  #else
> --- gcc/testsuite/g++.dg/asan/asan_test.cc.jj   2013-11-12 11:31:20.000000000 +0100
> +++ gcc/testsuite/g++.dg/asan/asan_test.cc      2014-05-22 13:08:39.223454867 +0200
> @@ -23,27 +23,10 @@ NOINLINE void *malloc_bbb(size_t size) {
>  NOINLINE void *malloc_aaa(size_t size) {
>    void *res = malloc_bbb(size); break_optimization(0); return res;}
>
> -#ifndef __APPLE__
> -NOINLINE void *memalign_fff(size_t alignment, size_t size) {
> -  void *res = memalign/**/(alignment, size); break_optimization(0); return res;}
> -NOINLINE void *memalign_eee(size_t alignment, size_t size) {
> -  void *res = memalign_fff(alignment, size); break_optimization(0); return res;}
> -NOINLINE void *memalign_ddd(size_t alignment, size_t size) {
> -  void *res = memalign_eee(alignment, size); break_optimization(0); return res;}
> -NOINLINE void *memalign_ccc(size_t alignment, size_t size) {
> -  void *res = memalign_ddd(alignment, size); break_optimization(0); return res;}
> -NOINLINE void *memalign_bbb(size_t alignment, size_t size) {
> -  void *res = memalign_ccc(alignment, size); break_optimization(0); return res;}
> -NOINLINE void *memalign_aaa(size_t alignment, size_t size) {
> -  void *res = memalign_bbb(alignment, size); break_optimization(0); return res;}
> -#endif  // __APPLE__
> -
> -
>  NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}
>  NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}
>  NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}
>
> -
>  template<typename T>
>  NOINLINE void uaf_test(int size, int off) {
>    char *p = (char *)malloc_aaa(size);
> @@ -88,19 +71,19 @@ TEST(AddressSanitizer, VariousMallocsTes
>    *c = 0;
>    delete c;
>
> -#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__)
> +#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
>    int *pm;
>    int pm_res = posix_memalign((void**)&pm, kPageSize, kPageSize);
>    EXPECT_EQ(0, pm_res);
>    free(pm);
> -#endif
> +#endif  // SANITIZER_TEST_HAS_POSIX_MEMALIGN
>
> -#if !defined(__APPLE__)
> +#if SANITIZER_TEST_HAS_MEMALIGN
>    int *ma = (int*)memalign(kPageSize, kPageSize);
>    EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);
>    ma[123] = 0;
>    free(ma);
> -#endif  // __APPLE__
> +#endif  // SANITIZER_TEST_HAS_MEMALIGN
>  }
>
>  TEST(AddressSanitizer, CallocTest) {
> @@ -109,13 +92,37 @@ TEST(AddressSanitizer, CallocTest) {
>    free(a);
>  }
>
> +TEST(AddressSanitizer, CallocReturnsZeroMem) {
> +  size_t sizes[] = {16, 1000, 10000, 100000, 2100000};
> +  for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {
> +    size_t size = sizes[s];
> +    for (size_t iter = 0; iter < 5; iter++) {
> +      char *x = Ident((char*)calloc(1, size));
> +      EXPECT_EQ(x[0], 0);
> +      EXPECT_EQ(x[size - 1], 0);
> +      EXPECT_EQ(x[size / 2], 0);
> +      EXPECT_EQ(x[size / 3], 0);
> +      EXPECT_EQ(x[size / 4], 0);
> +      memset(x, 0x42, size);
> +      free(Ident(x));
> +#if !defined(_WIN32)
> +      // FIXME: OOM on Windows. We should just make this a lit test
> +      // with quarantine size set to 1.
> +      free(Ident(malloc(Ident(1 << 27))));  // Try to drain the quarantine.
> +#endif
> +    }
> +  }
> +}
> +
> +#if !defined(_WIN32)  // No valloc on Windows.
>  TEST(AddressSanitizer, VallocTest) {
>    void *a = valloc(100);
>    EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
>    free(a);
>  }
> +#endif
>
> -#ifndef __APPLE__
> +#if SANITIZER_TEST_HAS_PVALLOC
>  TEST(AddressSanitizer, PvallocTest) {
>    char *a = (char*)pvalloc(kPageSize + 100);
>    EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
> @@ -127,8 +134,10 @@ TEST(AddressSanitizer, PvallocTest) {
>    a[101] = 1;  // we should not report an error here.
>    free(a);
>  }
> -#endif  // __APPLE__
> +#endif  // SANITIZER_TEST_HAS_PVALLOC
>
> +#if !defined(_WIN32)
> +// FIXME: Use an equivalent of pthread_setspecific on Windows.
>  void *TSDWorker(void *test_key) {
>    if (test_key) {
>      pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);
> @@ -158,6 +167,7 @@ TEST(AddressSanitizer, DISABLED_TSDTest)
>    PTHREAD_JOIN(th, NULL);
>    pthread_key_delete(test_key);
>  }
> +#endif
>
>  TEST(AddressSanitizer, UAF_char) {
>    const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
> @@ -168,6 +178,36 @@ TEST(AddressSanitizer, UAF_char) {
>    EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);
>  }
>
> +TEST(AddressSanitizer, UAF_long_double) {
> +  if (sizeof(long double) == sizeof(double)) return;
> +  long double *p = Ident(new long double[10]);
> +  EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[06]");
> +  EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[06]");
> +  delete [] Ident(p);
> +}
> +
> +#if !defined(_WIN32)
> +struct Packed5 {
> +  int x;
> +  char c;
> +} __attribute__((packed));
> +#else
> +# pragma pack(push, 1)
> +struct Packed5 {
> +  int x;
> +  char c;
> +};
> +# pragma pack(pop)
> +#endif
> +
> +TEST(AddressSanitizer, UAF_Packed5) {
> +  static_assert(sizeof(Packed5) == 5, "Please check the keywords used");
> +  Packed5 *p = Ident(new Packed5[2]);
> +  EXPECT_DEATH(p[0] = p[3], "READ of size 5");
> +  EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
> +  delete [] Ident(p);
> +}
> +
>  #if ASAN_HAS_BLACKLIST
>  TEST(AddressSanitizer, IgnoreTest) {
>    int *x = Ident(new int);
> @@ -244,41 +284,6 @@ TEST(AddressSanitizer, SignalTest) {
>  }  // namespace
>  #endif
>
> -static void MallocStress(size_t n) {
> -  uint32_t seed = my_rand();
> -  for (size_t iter = 0; iter < 10; iter++) {
> -    vector<void *> vec;
> -    for (size_t i = 0; i < n; i++) {
> -      if ((i % 3) == 0) {
> -        if (vec.empty()) continue;
> -        size_t idx = my_rand_r(&seed) % vec.size();
> -        void *ptr = vec[idx];
> -        vec[idx] = vec.back();
> -        vec.pop_back();
> -        free_aaa(ptr);
> -      } else {
> -        size_t size = my_rand_r(&seed) % 1000 + 1;
> -#ifndef __APPLE__
> -        size_t alignment = 1 << (my_rand_r(&seed) % 7 + 3);
> -        char *ptr = (char*)memalign_aaa(alignment, size);
> -#else
> -        char *ptr = (char*) malloc_aaa(size);
> -#endif
> -        vec.push_back(ptr);
> -        ptr[0] = 0;
> -        ptr[size-1] = 0;
> -        ptr[size/2] = 0;
> -      }
> -    }
> -    for (size_t i = 0; i < vec.size(); i++)
> -      free_aaa(vec[i]);
> -  }
> -}
> -
> -TEST(AddressSanitizer, MallocStressTest) {
> -  MallocStress((ASAN_LOW_MEMORY) ? 20000 : 200000);
> -}
> -
>  static void TestLargeMalloc(size_t size) {
>    char buff[1024];
>    sprintf(buff, "is located 1 bytes to the left of %lu-byte", (long)size);
> @@ -286,28 +291,21 @@ static void TestLargeMalloc(size_t size)
>  }
>
>  TEST(AddressSanitizer, LargeMallocTest) {
> -  for (int i = 113; i < (1 << 28); i = i * 2 + 13) {
> +  const int max_size = (SANITIZER_WORDSIZE == 32) ? 1 << 26 : 1 << 28;
> +  for (int i = 113; i < max_size; i = i * 2 + 13) {
>      TestLargeMalloc(i);
>    }
>  }
>
> -#if ASAN_LOW_MEMORY != 1
>  TEST(AddressSanitizer, HugeMallocTest) {
> -#ifdef __APPLE__
> -  // It was empirically found out that 1215 megabytes is the maximum amount of
> -  // memory available to the process under AddressSanitizer on 32-bit Mac 10.6.
> -  // 32-bit Mac 10.7 gives even less (< 1G).
> -  // (the libSystem malloc() allows allocating up to 2300 megabytes without
> -  // ASan).
> -  size_t n_megs = SANITIZER_WORDSIZE == 32 ? 500 : 4100;
> -#else
> -  size_t n_megs = SANITIZER_WORDSIZE == 32 ? 2600 : 4100;
> -#endif
> -  TestLargeMalloc(n_megs << 20);
> +  if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;
> +  size_t n_megs = 4100;
> +  EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,
> +               "is located 1 bytes to the left|"
> +               "AddressSanitizer failed to allocate");
>  }
> -#endif
>
> -#ifndef __APPLE__
> +#if SANITIZER_TEST_HAS_MEMALIGN
>  void MemalignRun(size_t align, size_t size, int idx) {
>    char *p = (char *)memalign(align, size);
>    Ident(p)[idx] = 0;
> @@ -323,20 +321,7 @@ TEST(AddressSanitizer, memalign) {
>                   "is located 1 bytes to the right");
>    }
>  }
> -#endif
> -
> -TEST(AddressSanitizer, ThreadedMallocStressTest) {
> -  const int kNumThreads = 4;
> -  const int kNumIterations = (ASAN_LOW_MEMORY) ? 10000 : 100000;
> -  pthread_t t[kNumThreads];
> -  for (int i = 0; i < kNumThreads; i++) {
> -    PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))MallocStress,
> -        (void*)kNumIterations);
> -  }
> -  for (int i = 0; i < kNumThreads; i++) {
> -    PTHREAD_JOIN(t[i], 0);
> -  }
> -}
> +#endif  // SANITIZER_TEST_HAS_MEMALIGN
>
>  void *ManyThreadsWorker(void *a) {
>    for (int iter = 0; iter < 100; iter++) {
> @@ -377,17 +362,30 @@ TEST(AddressSanitizer, ReallocTest) {
>    free(ptr2);
>  }
>
> +TEST(AddressSanitizer, ReallocFreedPointerTest) {
> +  void *ptr = Ident(malloc(42));
> +  ASSERT_TRUE(NULL != ptr);
> +  free(ptr);
> +  EXPECT_DEATH(ptr = realloc(ptr, 77), "attempting double-free");
> +}
> +
> +TEST(AddressSanitizer, ReallocInvalidPointerTest) {
> +  void *ptr = Ident(malloc(42));
> +  EXPECT_DEATH(ptr = realloc((int*)ptr + 1, 77), "attempting free.*not malloc");
> +  free(ptr);
> +}
> +
>  TEST(AddressSanitizer, ZeroSizeMallocTest) {
>    // Test that malloc(0) and similar functions don't return NULL.
>    void *ptr = Ident(malloc(0));
>    EXPECT_TRUE(NULL != ptr);
>    free(ptr);
> -#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__)
> +#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
>    int pm_res = posix_memalign(&ptr, 1<<20, 0);
>    EXPECT_EQ(0, pm_res);
>    EXPECT_TRUE(NULL != ptr);
>    free(ptr);
> -#endif
> +#endif  // SANITIZER_TEST_HAS_POSIX_MEMALIGN
>    int *int_ptr = new int[0];
>    int *int_ptr2 = new int[0];
>    EXPECT_TRUE(NULL != int_ptr);
> @@ -397,7 +395,7 @@ TEST(AddressSanitizer, ZeroSizeMallocTes
>    delete[] int_ptr2;
>  }
>
> -#ifndef __APPLE__
> +#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
>  static const char *kMallocUsableSizeErrorMsg =
>    "AddressSanitizer: attempting to call malloc_usable_size()";
>
> @@ -413,8 +411,9 @@ TEST(AddressSanitizer, MallocUsableSizeT
>                 kMallocUsableSizeErrorMsg);
>    free(array);
>    EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);
> +  delete int_ptr;
>  }
> -#endif
> +#endif  // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
>
>  void WrongFree() {
>    int *x = (int*)malloc(100 * sizeof(int));
> @@ -423,10 +422,14 @@ void WrongFree() {
>    free(x + 1);
>  }
>
> +#if !defined(_WIN32)  // FIXME: This should be a lit test.
>  TEST(AddressSanitizer, WrongFreeTest) {
> -  EXPECT_DEATH(WrongFree(),
> -               "ERROR: AddressSanitizer: attempting free.*not malloc");
> +  EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL
> +               "ERROR: AddressSanitizer: attempting free.*not malloc"
> +               ".*is located 4 bytes inside of 400-byte region"
> +               ".*allocated by thread");
>  }
> +#endif
>
>  void DoubleFree() {
>    int *x = (int*)malloc(100 * sizeof(int));
> @@ -437,6 +440,7 @@ void DoubleFree() {
>    abort();
>  }
>
> +#if !defined(_WIN32)  // FIXME: This should be a lit test.
>  TEST(AddressSanitizer, DoubleFreeTest) {
>    EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL
>                 "ERROR: AddressSanitizer: attempting double-free"
> @@ -444,20 +448,22 @@ TEST(AddressSanitizer, DoubleFreeTest) {
>                 ".*freed by thread T0 here"
>                 ".*previously allocated by thread T0 here");
>  }
> +#endif
>
>  template<int kSize>
>  NOINLINE void SizedStackTest() {
>    char a[kSize];
>    char  *A = Ident((char*)&a);
> +  const char *expected_death = "AddressSanitizer: stack-buffer-";
>    for (size_t i = 0; i < kSize; i++)
>      A[i] = i;
> -  EXPECT_DEATH(A[-1] = 0, "");
> -  EXPECT_DEATH(A[-20] = 0, "");
> -  EXPECT_DEATH(A[-31] = 0, "");
> -  EXPECT_DEATH(A[kSize] = 0, "");
> -  EXPECT_DEATH(A[kSize + 1] = 0, "");
> -  EXPECT_DEATH(A[kSize + 10] = 0, "");
> -  EXPECT_DEATH(A[kSize + 31] = 0, "");
> +  EXPECT_DEATH(A[-1] = 0, expected_death);
> +  EXPECT_DEATH(A[-5] = 0, expected_death);
> +  EXPECT_DEATH(A[kSize] = 0, expected_death);
> +  EXPECT_DEATH(A[kSize + 1] = 0, expected_death);
> +  EXPECT_DEATH(A[kSize + 5] = 0, expected_death);
> +  if (kSize > 16)
> +    EXPECT_DEATH(A[kSize + 31] = 0, expected_death);
>  }
>
>  TEST(AddressSanitizer, SimpleStackTest) {
> @@ -478,6 +484,9 @@ TEST(AddressSanitizer, SimpleStackTest)
>    SizedStackTest<128>();
>  }
>
> +#if !defined(_WIN32)
> +// FIXME: It's a bit hard to write multi-line death test expectations
> +// in a portable way.  Anyways, this should just be turned into a lit test.
>  TEST(AddressSanitizer, ManyStackObjectsTest) {
>    char XXX[10];
>    char YYY[20];
> @@ -486,6 +495,47 @@ TEST(AddressSanitizer, ManyStackObjectsT
>    Ident(YYY);
>    EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");
>  }
> +#endif
> +
> +#if 0  // This test requires online symbolizer.
> +// Moved to lit_tests/stack-oob-frames.cc.
> +// Reenable here once we have online symbolizer by default.
> +NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {
> +  char d[4] = {0};
> +  char *D = Ident(d);
> +  switch (frame) {
> +    case 3: a[5]++; break;
> +    case 2: b[5]++; break;
> +    case 1: c[5]++; break;
> +    case 0: D[5]++; break;
> +  }
> +}
> +NOINLINE static void Frame1(int frame, char *a, char *b) {
> +  char c[4] = {0}; Frame0(frame, a, b, c);
> +  break_optimization(0);
> +}
> +NOINLINE static void Frame2(int frame, char *a) {
> +  char b[4] = {0}; Frame1(frame, a, b);
> +  break_optimization(0);
> +}
> +NOINLINE static void Frame3(int frame) {
> +  char a[4] = {0}; Frame2(frame, a);
> +  break_optimization(0);
> +}
> +
> +TEST(AddressSanitizer, GuiltyStackFrame0Test) {
> +  EXPECT_DEATH(Frame3(0), "located .*in frame <.*Frame0");
> +}
> +TEST(AddressSanitizer, GuiltyStackFrame1Test) {
> +  EXPECT_DEATH(Frame3(1), "located .*in frame <.*Frame1");
> +}
> +TEST(AddressSanitizer, GuiltyStackFrame2Test) {
> +  EXPECT_DEATH(Frame3(2), "located .*in frame <.*Frame2");
> +}
> +TEST(AddressSanitizer, GuiltyStackFrame3Test) {
> +  EXPECT_DEATH(Frame3(3), "located .*in frame <.*Frame3");
> +}
> +#endif
>
>  NOINLINE void LongJmpFunc1(jmp_buf buf) {
>    // create three red zones for these two stack objects.
> @@ -498,6 +548,24 @@ NOINLINE void LongJmpFunc1(jmp_buf buf)
>    longjmp(buf, 1);
>  }
>
> +NOINLINE void TouchStackFunc() {
> +  int a[100];  // long array will intersect with redzones from LongJmpFunc1.
> +  int *A = Ident(a);
> +  for (int i = 0; i < 100; i++)
> +    A[i] = i*i;
> +}
> +
> +// Test that we handle longjmp and do not report false positives on stack.
> +TEST(AddressSanitizer, LongJmpTest) {
> +  static jmp_buf buf;
> +  if (!setjmp(buf)) {
> +    LongJmpFunc1(buf);
> +  } else {
> +    TouchStackFunc();
> +  }
> +}
> +
> +#if !defined(_WIN32)  // Only basic longjmp is available on Windows.
>  NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
>    // create three red zones for these two stack objects.
>    int a;
> @@ -531,25 +599,10 @@ NOINLINE void SigLongJmpFunc1(sigjmp_buf
>    siglongjmp(buf, 1);
>  }
>
> -
> -NOINLINE void TouchStackFunc() {
> -  int a[100];  // long array will intersect with redzones from LongJmpFunc1.
> -  int *A = Ident(a);
> -  for (int i = 0; i < 100; i++)
> -    A[i] = i*i;
> -}
> -
> -// Test that we handle longjmp and do not report fals positives on stack.
> -TEST(AddressSanitizer, LongJmpTest) {
> -  static jmp_buf buf;
> -  if (!setjmp(buf)) {
> -    LongJmpFunc1(buf);
> -  } else {
> -    TouchStackFunc();
> -  }
> -}
> -
> -#if not defined(__ANDROID__)
> +#if !defined(__ANDROID__) && \
> +    !defined(__powerpc64__) && !defined(__powerpc__)
> +// Does not work on Power:
> +// https://code.google.com/p/address-sanitizer/issues/detail?id=185
>  TEST(AddressSanitizer, BuiltinLongJmpTest) {
>    static jmp_buf buf;
>    if (!__builtin_setjmp((void**)buf)) {
> @@ -558,7 +611,8 @@ TEST(AddressSanitizer, BuiltinLongJmpTes
>      TouchStackFunc();
>    }
>  }
> -#endif  // not defined(__ANDROID__)
> +#endif  // !defined(__ANDROID__) && !defined(__powerpc64__) &&
> +        // !defined(__powerpc__)
>
>  TEST(AddressSanitizer, UnderscopeLongJmpTest) {
>    static jmp_buf buf;
> @@ -577,8 +631,10 @@ TEST(AddressSanitizer, SigLongJmpTest) {
>      TouchStackFunc();
>    }
>  }
> +#endif
>
> -#ifdef __EXCEPTIONS
> +// FIXME: Why does clang-cl define __EXCEPTIONS?
> +#if defined(__EXCEPTIONS) && !defined(_WIN32)
>  NOINLINE void ThrowFunc() {
>    // create three red zones for these two stack objects.
>    int a;
> @@ -626,7 +682,8 @@ TEST(AddressSanitizer, ThreadStackReuseT
>    PTHREAD_JOIN(t, 0);
>  }
>
> -#if defined(__i386__) || defined(__x86_64__)
> +#if defined(__i686__) || defined(__x86_64__)
> +#include <emmintrin.h>
>  TEST(AddressSanitizer, Store128Test) {
>    char *a = Ident((char*)malloc(Ident(12)));
>    char *p = a;
> @@ -644,11 +701,19 @@ TEST(AddressSanitizer, Store128Test) {
>  }
>  #endif
>
> +// FIXME: All tests that use this function should be turned into lit tests.
>  string RightOOBErrorMessage(int oob_distance, bool is_write) {
>    assert(oob_distance >= 0);
>    char expected_str[100];
> -  sprintf(expected_str, ASAN_PCRE_DOTALL "%s.*located %d bytes to the right",
> -          is_write ? "WRITE" : "READ", oob_distance);
> +  sprintf(expected_str, ASAN_PCRE_DOTALL
> +#if !GTEST_USES_SIMPLE_RE
> +          "buffer-overflow.*%s.*"
> +#endif
> +          "located %d bytes to the right",
> +#if !GTEST_USES_SIMPLE_RE
> +          is_write ? "WRITE" : "READ",
> +#endif
> +          oob_distance);
>    return string(expected_str);
>  }
>
> @@ -660,11 +725,19 @@ string RightOOBReadMessage(int oob_dista
>    return RightOOBErrorMessage(oob_distance, /*is_write*/false);
>  }
>
> +// FIXME: All tests that use this function should be turned into lit tests.
>  string LeftOOBErrorMessage(int oob_distance, bool is_write) {
>    assert(oob_distance > 0);
>    char expected_str[100];
> -  sprintf(expected_str, ASAN_PCRE_DOTALL "%s.*located %d bytes to the left",
> -          is_write ? "WRITE" : "READ", oob_distance);
> +  sprintf(expected_str,
> +#if !GTEST_USES_SIMPLE_RE
> +          ASAN_PCRE_DOTALL "%s.*"
> +#endif
> +          "located %d bytes to the left",
> +#if !GTEST_USES_SIMPLE_RE
> +          is_write ? "WRITE" : "READ",
> +#endif
> +          oob_distance);
>    return string(expected_str);
>  }
>
> @@ -818,6 +891,7 @@ void ThreadedTestSpawn() {
>    PTHREAD_JOIN(t, 0);
>  }
>
> +#if !defined(_WIN32)  // FIXME: This should be a lit test.
>  TEST(AddressSanitizer, ThreadedTest) {
>    EXPECT_DEATH(ThreadedTestSpawn(),
>                 ASAN_PCRE_DOTALL
> @@ -825,6 +899,7 @@ TEST(AddressSanitizer, ThreadedTest) {
>                 ".*Thread T.*created"
>                 ".*Thread T.*created");
>  }
> +#endif
>
>  void *ThreadedTestFunc(void *unused) {
>    // Check if prctl(PR_SET_NAME) is supported. Return if not.
> @@ -855,7 +930,11 @@ TEST(AddressSanitizer, ShadowGapTest) {
>  #if SANITIZER_WORDSIZE == 32
>    char *addr = (char*)0x22000000;
>  #else
> +# if defined(__powerpc64__)
> +  char *addr = (char*)0x024000800000;
> +# else
>    char *addr = (char*)0x0000100000080000;
> +# endif
>  #endif
>    EXPECT_DEATH(*addr = 1, "AddressSanitizer: SEGV on unknown");
>  }
> @@ -1015,7 +1094,8 @@ TEST(AddressSanitizer, PthreadExitTest)
>    }
>  }
>
> -#ifdef __EXCEPTIONS
> +// FIXME: Why does clang-cl define __EXCEPTIONS?
> +#if defined(__EXCEPTIONS) && !defined(_WIN32)
>  NOINLINE static void StackReuseAndException() {
>    int large_stack[1000];
>    Ident(large_stack);
> @@ -1033,12 +1113,14 @@ TEST(AddressSanitizer, DISABLED_StressSt
>  }
>  #endif
>
> +#if !defined(_WIN32)
>  TEST(AddressSanitizer, MlockTest) {
>    EXPECT_EQ(0, mlockall(MCL_CURRENT));
>    EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));
>    EXPECT_EQ(0, munlockall());
>    EXPECT_EQ(0, munlock((void*)0x987, 0x654));
>  }
> +#endif
>
>  struct LargeStruct {
>    int foo[100];
> @@ -1051,19 +1133,26 @@ TEST(AddressSanitizer, LargeStructCopyTe
>    *Ident(&a) = *Ident(&a);
>  }
>
> -ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
> -static void NoAddressSafety() {
> +ATTRIBUTE_NO_SANITIZE_ADDRESS
> +static void NoSanitizeAddress() {
>    char *foo = new char[10];
>    Ident(foo)[10] = 0;
>    delete [] foo;
>  }
>
> -TEST(AddressSanitizer, AttributeNoAddressSafetyTest) {
> -  Ident(NoAddressSafety)();
> +TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
> +  Ident(NoSanitizeAddress)();
>  }
>
> -// It doesn't work on Android, as calls to new/delete go through malloc/free.
> -#if !defined(ANDROID) && !defined(__ANDROID__)
> +// The new/delete/etc mismatch checks don't work on Android,
> +//   as calls to new/delete go through malloc/free.
> +// OS X support is tracked here:
> +//   https://code.google.com/p/address-sanitizer/issues/detail?id=131
> +// Windows support is tracked here:
> +//   https://code.google.com/p/address-sanitizer/issues/detail?id=309
> +#if !defined(ANDROID) && !defined(__ANDROID__) && \
> +    !defined(__APPLE__) && \
> +    !defined(_WIN32)
>  static string MismatchStr(const string &str) {
>    return string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;
>  }
> @@ -1177,3 +1266,18 @@ TEST(AddressSanitizer, LongDoubleNegativ
>    memcpy(Ident(&a), Ident(&b), sizeof(long double));
>    memcpy(Ident(&c), Ident(&b), sizeof(long double));
>  }
> +
> +#if !defined(_WIN32)
> +TEST(AddressSanitizer, pthread_getschedparam) {
> +  int policy;
> +  struct sched_param param;
> +  EXPECT_DEATH(
> +      pthread_getschedparam(pthread_self(), &policy, Ident(&param) + 2),
> +      "AddressSanitizer: stack-buffer-.*flow");
> +  EXPECT_DEATH(
> +      pthread_getschedparam(pthread_self(), Ident(&policy) - 1, &param),
> +      "AddressSanitizer: stack-buffer-.*flow");
> +  int res = pthread_getschedparam(pthread_self(), &policy, &param);
> +  ASSERT_EQ(0, res);
> +}
> +#endif
> --- gcc/testsuite/g++.dg/asan/sanitizer_pthread_wrappers.h.jj   2014-05-22 13:20:42.496012107 +0200
> +++ gcc/testsuite/g++.dg/asan/sanitizer_pthread_wrappers.h      2014-05-22 13:20:45.523996247 +0200
> @@ -0,0 +1,64 @@
> +//===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===//
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file is a part of *Sanitizer runtime.
> +// It provides handy wrappers for thread manipulation, that:
> +//  a) assert on any failure rather than returning an error code
> +//  b) defines pthread-like interface on platforms where where <pthread.h>
> +//     is not supplied by default.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef SANITIZER_PTHREAD_WRAPPERS_H
> +#define SANITIZER_PTHREAD_WRAPPERS_H
> +
> +#include "sanitizer_test_utils.h"
> +
> +#if !defined(_WIN32)
> +# include <pthread.h>
> +// Simply forward the arguments and check that the pthread functions succeed.
> +# define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))
> +# define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))
> +#else
> +typedef HANDLE pthread_t;
> +
> +struct PthreadHelperCreateThreadInfo {
> +  void *(*start_routine)(void *);
> +  void *arg;
> +};
> +
> +inline DWORD WINAPI PthreadHelperThreadProc(void *arg) {
> +  PthreadHelperCreateThreadInfo *start_data =
> +      reinterpret_cast<PthreadHelperCreateThreadInfo*>(arg);
> +  void *ret = (start_data->start_routine)(start_data->arg);
> +  delete start_data;
> +  return (DWORD)ret;
> +}
> +
> +inline void PTHREAD_CREATE(pthread_t *thread, void *attr,
> +                           void *(*start_routine)(void *), void *arg) {
> +  ASSERT_EQ(0, attr) << "Thread attributes are not supported yet.";
> +  PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo;
> +  data->start_routine = start_routine;
> +  data->arg = arg;
> +  *thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0);
> +  ASSERT_NE(nullptr, *thread) << "Failed to create a thread.";
> +}
> +
> +inline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) {
> +  ASSERT_EQ(0, value_ptr) << "Nonzero value_ptr is not supported yet.";
> +  ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE));
> +  ASSERT_NE(0, CloseHandle(thread));
> +}
> +
> +inline void pthread_exit(void *retval) {
> +  ASSERT_EQ(0, retval) << "Nonzero retval is not supported yet.";
> +  ExitThread((DWORD)retval);
> +}
> +#endif  // _WIN32
> +
> +#endif  // SANITIZER_PTHREAD_WRAPPERS_H
> --- gcc/testsuite/g++.dg/asan/sanitizer_test_config.h.jj        2014-05-22 13:11:24.552661120 +0200
> +++ gcc/testsuite/g++.dg/asan/sanitizer_test_config.h   2014-05-22 13:11:28.153650267 +0200
> @@ -0,0 +1,28 @@
> +//===-- sanitizer_test_config.h ---------------------------------*- C++ -*-===//
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file is a part of *Sanitizer runtime.
> +//
> +//===----------------------------------------------------------------------===//
> +#if !defined(INCLUDED_FROM_SANITIZER_TEST_UTILS_H)
> +# error "This file should be included into sanitizer_test_utils.h only"
> +#endif
> +
> +#ifndef SANITIZER_TEST_CONFIG_H
> +#define SANITIZER_TEST_CONFIG_H
> +
> +#include <vector>
> +#include <string>
> +#include <map>
> +
> +#if SANITIZER_USE_DEJAGNU_GTEST
> +# include "dejagnu-gtest.h"
> +#else
> +# include "gtest/gtest.h"
> +#endif
> +
> +#endif  // SANITIZER_TEST_CONFIG_H
>
>
>         Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]