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
18namespace __tsan {
19
20TEST(Mman, Internal) {
21 char *p = (char *)Alloc(10);
22 EXPECT_NE(p, (char*)0);
23 char *p2 = (char *)Alloc(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 Free(p);
33 Free(p2);
34}
35
36TEST(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
50TEST(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
97TEST(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
110TEST(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(size: 10));
119 EXPECT_EQ(20U, __sanitizer_get_estimated_allocated_size(size: 20));
120 EXPECT_EQ(100U, __sanitizer_get_estimated_allocated_size(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
139TEST(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
161TEST(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
178TEST(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
188TEST(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

source code of compiler-rt/lib/tsan/tests/unit/tsan_mman_test.cpp