Home | History | Annotate | 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 "tsan_mman.h"
     15 #include "tsan_rtl.h"
     16 #include "gtest/gtest.h"
     17 
     18 extern "C" {
     19 uptr __tsan_get_current_allocated_bytes();
     20 uptr __tsan_get_heap_size();
     21 uptr __tsan_get_free_bytes();
     22 uptr __tsan_get_unmapped_bytes();
     23 uptr __tsan_get_estimated_allocated_size(uptr size);
     24 bool __tsan_get_ownership(void *p);
     25 uptr __tsan_get_allocated_size(void *p);
     26 }
     27 
     28 namespace __tsan {
     29 
     30 TEST(Mman, Internal) {
     31   ScopedInRtl in_rtl;
     32   char *p = (char*)internal_alloc(MBlockScopedBuf, 10);
     33   EXPECT_NE(p, (char*)0);
     34   char *p2 = (char*)internal_alloc(MBlockScopedBuf, 20);
     35   EXPECT_NE(p2, (char*)0);
     36   EXPECT_NE(p2, p);
     37   for (int i = 0; i < 10; i++) {
     38     p[i] = 42;
     39   }
     40   for (int i = 0; i < 20; i++) {
     41     ((char*)p2)[i] = 42;
     42   }
     43   internal_free(p);
     44   internal_free(p2);
     45 }
     46 
     47 TEST(Mman, User) {
     48   ScopedInRtl in_rtl;
     49   ThreadState *thr = cur_thread();
     50   uptr pc = 0;
     51   char *p = (char*)user_alloc(thr, pc, 10);
     52   EXPECT_NE(p, (char*)0);
     53   char *p2 = (char*)user_alloc(thr, pc, 20);
     54   EXPECT_NE(p2, (char*)0);
     55   EXPECT_NE(p2, p);
     56   MBlock *b = user_mblock(thr, p);
     57   EXPECT_NE(b, (MBlock*)0);
     58   EXPECT_EQ(b->Size(), (uptr)10);
     59   MBlock *b2 = user_mblock(thr, p2);
     60   EXPECT_NE(b2, (MBlock*)0);
     61   EXPECT_EQ(b2->Size(), (uptr)20);
     62   for (int i = 0; i < 10; i++) {
     63     p[i] = 42;
     64     EXPECT_EQ(b, user_mblock(thr, p + i));
     65   }
     66   for (int i = 0; i < 20; i++) {
     67     ((char*)p2)[i] = 42;
     68     EXPECT_EQ(b2, user_mblock(thr, p2 + i));
     69   }
     70   user_free(thr, pc, p);
     71   user_free(thr, pc, p2);
     72 }
     73 
     74 TEST(Mman, UserRealloc) {
     75   ScopedInRtl in_rtl;
     76   ThreadState *thr = cur_thread();
     77   uptr pc = 0;
     78   {
     79     void *p = user_realloc(thr, pc, 0, 0);
     80     // Strictly saying this is incorrect, realloc(NULL, N) is equivalent to
     81     // malloc(N), thus must return non-NULL pointer.
     82     EXPECT_EQ(p, (void*)0);
     83   }
     84   {
     85     void *p = user_realloc(thr, pc, 0, 100);
     86     EXPECT_NE(p, (void*)0);
     87     memset(p, 0xde, 100);
     88     user_free(thr, pc, p);
     89   }
     90   {
     91     void *p = user_alloc(thr, pc, 100);
     92     EXPECT_NE(p, (void*)0);
     93     memset(p, 0xde, 100);
     94     void *p2 = user_realloc(thr, pc, p, 0);
     95     EXPECT_EQ(p2, (void*)0);
     96   }
     97   {
     98     void *p = user_realloc(thr, pc, 0, 100);
     99     EXPECT_NE(p, (void*)0);
    100     memset(p, 0xde, 100);
    101     void *p2 = user_realloc(thr, pc, p, 10000);
    102     EXPECT_NE(p2, (void*)0);
    103     for (int i = 0; i < 100; i++)
    104       EXPECT_EQ(((char*)p2)[i], (char)0xde);
    105     memset(p2, 0xde, 10000);
    106     user_free(thr, pc, p2);
    107   }
    108   {
    109     void *p = user_realloc(thr, pc, 0, 10000);
    110     EXPECT_NE(p, (void*)0);
    111     memset(p, 0xde, 10000);
    112     void *p2 = user_realloc(thr, pc, p, 10);
    113     EXPECT_NE(p2, (void*)0);
    114     for (int i = 0; i < 10; i++)
    115       EXPECT_EQ(((char*)p2)[i], (char)0xde);
    116     user_free(thr, pc, p2);
    117   }
    118 }
    119 
    120 TEST(Mman, UsableSize) {
    121   ScopedInRtl in_rtl;
    122   ThreadState *thr = cur_thread();
    123   uptr pc = 0;
    124   char *p = (char*)user_alloc(thr, pc, 10);
    125   char *p2 = (char*)user_alloc(thr, pc, 20);
    126   EXPECT_EQ(0U, user_alloc_usable_size(thr, pc, NULL));
    127   EXPECT_EQ(10U, user_alloc_usable_size(thr, pc, p));
    128   EXPECT_EQ(20U, user_alloc_usable_size(thr, pc, p2));
    129   user_free(thr, pc, p);
    130   user_free(thr, pc, p2);
    131 }
    132 
    133 TEST(Mman, Stats) {
    134   ScopedInRtl in_rtl;
    135   ThreadState *thr = cur_thread();
    136 
    137   uptr alloc0 = __tsan_get_current_allocated_bytes();
    138   uptr heap0 = __tsan_get_heap_size();
    139   uptr free0 = __tsan_get_free_bytes();
    140   uptr unmapped0 = __tsan_get_unmapped_bytes();
    141 
    142   EXPECT_EQ(__tsan_get_estimated_allocated_size(10), (uptr)10);
    143   EXPECT_EQ(__tsan_get_estimated_allocated_size(20), (uptr)20);
    144   EXPECT_EQ(__tsan_get_estimated_allocated_size(100), (uptr)100);
    145 
    146   char *p = (char*)user_alloc(thr, 0, 10);
    147   EXPECT_EQ(__tsan_get_ownership(p), true);
    148   EXPECT_EQ(__tsan_get_allocated_size(p), (uptr)10);
    149 
    150   EXPECT_EQ(__tsan_get_current_allocated_bytes(), alloc0 + 16);
    151   EXPECT_GE(__tsan_get_heap_size(), heap0);
    152   EXPECT_EQ(__tsan_get_free_bytes(), free0);
    153   EXPECT_EQ(__tsan_get_unmapped_bytes(), unmapped0);
    154 
    155   user_free(thr, 0, p);
    156 
    157   EXPECT_EQ(__tsan_get_current_allocated_bytes(), alloc0);
    158   EXPECT_GE(__tsan_get_heap_size(), heap0);
    159   EXPECT_EQ(__tsan_get_free_bytes(), free0);
    160   EXPECT_EQ(__tsan_get_unmapped_bytes(), unmapped0);
    161 }
    162 
    163 TEST(Mman, CallocOverflow) {
    164   size_t kArraySize = 4096;
    165   volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
    166   volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
    167   volatile void *p = calloc(kArraySize, kArraySize2);  // Should return 0.
    168   EXPECT_EQ(0L, p);
    169 }
    170 
    171 }  // namespace __tsan
    172