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