Home | History | Annotate | Line # | Download | only in unit
      1 //===-- tsan_mman_test.cc -------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of ThreadSanitizer (TSan), a race detector.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #include <limits>
     14 #include <sanitizer/allocator_interface.h>
     15 #include "tsan_mman.h"
     16 #include "tsan_rtl.h"
     17 #include "gtest/gtest.h"
     18 
     19 namespace __tsan {
     20 
     21 TEST(Mman, Internal) {
     22   char *p = (char*)internal_alloc(MBlockScopedBuf, 10);
     23   EXPECT_NE(p, (char*)0);
     24   char *p2 = (char*)internal_alloc(MBlockScopedBuf, 20);
     25   EXPECT_NE(p2, (char*)0);
     26   EXPECT_NE(p2, p);
     27   for (int i = 0; i < 10; i++) {
     28     p[i] = 42;
     29   }
     30   for (int i = 0; i < 20; i++) {
     31     ((char*)p2)[i] = 42;
     32   }
     33   internal_free(p);
     34   internal_free(p2);
     35 }
     36 
     37 TEST(Mman, User) {
     38   ThreadState *thr = cur_thread();
     39   uptr pc = 0;
     40   char *p = (char*)user_alloc(thr, pc, 10);
     41   EXPECT_NE(p, (char*)0);
     42   char *p2 = (char*)user_alloc(thr, pc, 20);
     43   EXPECT_NE(p2, (char*)0);
     44   EXPECT_NE(p2, p);
     45   EXPECT_EQ(10U, user_alloc_usable_size(p));
     46   EXPECT_EQ(20U, user_alloc_usable_size(p2));
     47   user_free(thr, pc, p);
     48   user_free(thr, pc, p2);
     49 }
     50 
     51 TEST(Mman, UserRealloc) {
     52   ThreadState *thr = cur_thread();
     53   uptr pc = 0;
     54   {
     55     void *p = user_realloc(thr, pc, 0, 0);
     56     // Realloc(NULL, N) is equivalent to malloc(N), thus must return
     57     // non-NULL pointer.
     58     EXPECT_NE(p, (void*)0);
     59     user_free(thr, pc, p);
     60   }
     61   {
     62     void *p = user_realloc(thr, pc, 0, 100);
     63     EXPECT_NE(p, (void*)0);
     64     memset(p, 0xde, 100);
     65     user_free(thr, pc, p);
     66   }
     67   {
     68     void *p = user_alloc(thr, pc, 100);
     69     EXPECT_NE(p, (void*)0);
     70     memset(p, 0xde, 100);
     71     // Realloc(P, 0) is equivalent to free(P) and returns NULL.
     72     void *p2 = user_realloc(thr, pc, p, 0);
     73     EXPECT_EQ(p2, (void*)0);
     74   }
     75   {
     76     void *p = user_realloc(thr, pc, 0, 100);
     77     EXPECT_NE(p, (void*)0);
     78     memset(p, 0xde, 100);
     79     void *p2 = user_realloc(thr, pc, p, 10000);
     80     EXPECT_NE(p2, (void*)0);
     81     for (int i = 0; i < 100; i++)
     82       EXPECT_EQ(((char*)p2)[i], (char)0xde);
     83     memset(p2, 0xde, 10000);
     84     user_free(thr, pc, p2);
     85   }
     86   {
     87     void *p = user_realloc(thr, pc, 0, 10000);
     88     EXPECT_NE(p, (void*)0);
     89     memset(p, 0xde, 10000);
     90     void *p2 = user_realloc(thr, pc, p, 10);
     91     EXPECT_NE(p2, (void*)0);
     92     for (int i = 0; i < 10; i++)
     93       EXPECT_EQ(((char*)p2)[i], (char)0xde);
     94     user_free(thr, pc, p2);
     95   }
     96 }
     97 
     98 TEST(Mman, UsableSize) {
     99   ThreadState *thr = cur_thread();
    100   uptr pc = 0;
    101   char *p = (char*)user_alloc(thr, pc, 10);
    102   char *p2 = (char*)user_alloc(thr, pc, 20);
    103   EXPECT_EQ(0U, user_alloc_usable_size(NULL));
    104   EXPECT_EQ(10U, user_alloc_usable_size(p));
    105   EXPECT_EQ(20U, user_alloc_usable_size(p2));
    106   user_free(thr, pc, p);
    107   user_free(thr, pc, p2);
    108   EXPECT_EQ(0U, user_alloc_usable_size((void*)0x4123));
    109 }
    110 
    111 TEST(Mman, Stats) {
    112   ThreadState *thr = cur_thread();
    113 
    114   uptr alloc0 = __sanitizer_get_current_allocated_bytes();
    115   uptr heap0 = __sanitizer_get_heap_size();
    116   uptr free0 = __sanitizer_get_free_bytes();
    117   uptr unmapped0 = __sanitizer_get_unmapped_bytes();
    118 
    119   EXPECT_EQ(10U, __sanitizer_get_estimated_allocated_size(10));
    120   EXPECT_EQ(20U, __sanitizer_get_estimated_allocated_size(20));
    121   EXPECT_EQ(100U, __sanitizer_get_estimated_allocated_size(100));
    122 
    123   char *p = (char*)user_alloc(thr, 0, 10);
    124   EXPECT_TRUE(__sanitizer_get_ownership(p));
    125   EXPECT_EQ(10U, __sanitizer_get_allocated_size(p));
    126 
    127   EXPECT_EQ(alloc0 + 16, __sanitizer_get_current_allocated_bytes());
    128   EXPECT_GE(__sanitizer_get_heap_size(), heap0);
    129   EXPECT_EQ(free0, __sanitizer_get_free_bytes());
    130   EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());
    131 
    132   user_free(thr, 0, p);
    133 
    134   EXPECT_EQ(alloc0, __sanitizer_get_current_allocated_bytes());
    135   EXPECT_GE(__sanitizer_get_heap_size(), heap0);
    136   EXPECT_EQ(free0, __sanitizer_get_free_bytes());
    137   EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());
    138 }
    139 
    140 TEST(Mman, Valloc) {
    141   ThreadState *thr = cur_thread();
    142   uptr page_size = GetPageSizeCached();
    143 
    144   void *p = user_valloc(thr, 0, 100);
    145   EXPECT_NE(p, (void*)0);
    146   user_free(thr, 0, p);
    147 
    148   p = user_pvalloc(thr, 0, 100);
    149   EXPECT_NE(p, (void*)0);
    150   user_free(thr, 0, p);
    151 
    152   p = user_pvalloc(thr, 0, 0);
    153   EXPECT_NE(p, (void*)0);
    154   EXPECT_EQ(page_size, __sanitizer_get_allocated_size(p));
    155   user_free(thr, 0, p);
    156 }
    157 
    158 #if !SANITIZER_DEBUG
    159 // EXPECT_DEATH clones a thread with 4K stack,
    160 // which is overflown by tsan memory accesses functions in debug mode.
    161 
    162 TEST(Mman, Memalign) {
    163   ThreadState *thr = cur_thread();
    164 
    165   void *p = user_memalign(thr, 0, 8, 100);
    166   EXPECT_NE(p, (void*)0);
    167   user_free(thr, 0, p);
    168 
    169   // TODO(alekseyshl): Remove this death test when memalign is verified by
    170   // tests in sanitizer_common.
    171   p = NULL;
    172   EXPECT_DEATH(p = user_memalign(thr, 0, 7, 100),
    173                "invalid-allocation-alignment");
    174   EXPECT_EQ(0L, p);
    175 }
    176 
    177 #endif
    178 
    179 TEST(Mman, PosixMemalign) {
    180   ThreadState *thr = cur_thread();
    181 
    182   void *p = NULL;
    183   int res = user_posix_memalign(thr, 0, &p, 8, 100);
    184   EXPECT_NE(p, (void*)0);
    185   EXPECT_EQ(res, 0);
    186   user_free(thr, 0, p);
    187 }
    188 
    189 TEST(Mman, AlignedAlloc) {
    190   ThreadState *thr = cur_thread();
    191 
    192   void *p = user_aligned_alloc(thr, 0, 8, 64);
    193   EXPECT_NE(p, (void*)0);
    194   user_free(thr, 0, p);
    195 }
    196 
    197 }  // namespace __tsan
    198