]> git.proxmox.com Git - rustc.git/blob - src/compiler-rt/lib/tsan/tests/unit/tsan_mman_test.cc
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / compiler-rt / lib / tsan / tests / unit / tsan_mman_test.cc
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 // Strictly saying this is incorrect, realloc(NULL, N) is equivalent to
57 // malloc(N), thus must return non-NULL pointer.
58 EXPECT_EQ(p, (void*)0);
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 void *p2 = user_realloc(thr, pc, p, 0);
71 EXPECT_EQ(p2, (void*)0);
72 }
73 {
74 void *p = user_realloc(thr, pc, 0, 100);
75 EXPECT_NE(p, (void*)0);
76 memset(p, 0xde, 100);
77 void *p2 = user_realloc(thr, pc, p, 10000);
78 EXPECT_NE(p2, (void*)0);
79 for (int i = 0; i < 100; i++)
80 EXPECT_EQ(((char*)p2)[i], (char)0xde);
81 memset(p2, 0xde, 10000);
82 user_free(thr, pc, p2);
83 }
84 {
85 void *p = user_realloc(thr, pc, 0, 10000);
86 EXPECT_NE(p, (void*)0);
87 memset(p, 0xde, 10000);
88 void *p2 = user_realloc(thr, pc, p, 10);
89 EXPECT_NE(p2, (void*)0);
90 for (int i = 0; i < 10; i++)
91 EXPECT_EQ(((char*)p2)[i], (char)0xde);
92 user_free(thr, pc, p2);
93 }
94 }
95
96 TEST(Mman, UsableSize) {
97 ThreadState *thr = cur_thread();
98 uptr pc = 0;
99 char *p = (char*)user_alloc(thr, pc, 10);
100 char *p2 = (char*)user_alloc(thr, pc, 20);
101 EXPECT_EQ(0U, user_alloc_usable_size(NULL));
102 EXPECT_EQ(10U, user_alloc_usable_size(p));
103 EXPECT_EQ(20U, user_alloc_usable_size(p2));
104 user_free(thr, pc, p);
105 user_free(thr, pc, p2);
106 EXPECT_EQ(0U, user_alloc_usable_size((void*)0x4123));
107 }
108
109 TEST(Mman, Stats) {
110 ThreadState *thr = cur_thread();
111
112 uptr alloc0 = __sanitizer_get_current_allocated_bytes();
113 uptr heap0 = __sanitizer_get_heap_size();
114 uptr free0 = __sanitizer_get_free_bytes();
115 uptr unmapped0 = __sanitizer_get_unmapped_bytes();
116
117 EXPECT_EQ(10U, __sanitizer_get_estimated_allocated_size(10));
118 EXPECT_EQ(20U, __sanitizer_get_estimated_allocated_size(20));
119 EXPECT_EQ(100U, __sanitizer_get_estimated_allocated_size(100));
120
121 char *p = (char*)user_alloc(thr, 0, 10);
122 EXPECT_TRUE(__sanitizer_get_ownership(p));
123 EXPECT_EQ(10U, __sanitizer_get_allocated_size(p));
124
125 EXPECT_EQ(alloc0 + 16, __sanitizer_get_current_allocated_bytes());
126 EXPECT_GE(__sanitizer_get_heap_size(), heap0);
127 EXPECT_EQ(free0, __sanitizer_get_free_bytes());
128 EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());
129
130 user_free(thr, 0, p);
131
132 EXPECT_EQ(alloc0, __sanitizer_get_current_allocated_bytes());
133 EXPECT_GE(__sanitizer_get_heap_size(), heap0);
134 EXPECT_EQ(free0, __sanitizer_get_free_bytes());
135 EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());
136 }
137
138 TEST(Mman, CallocOverflow) {
139 #if SANITIZER_DEBUG
140 // EXPECT_DEATH clones a thread with 4K stack,
141 // which is overflown by tsan memory accesses functions in debug mode.
142 return;
143 #endif
144 size_t kArraySize = 4096;
145 volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
146 volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
147 volatile void *p = NULL;
148 EXPECT_DEATH(p = calloc(kArraySize, kArraySize2),
149 "allocator is terminating the process instead of returning 0");
150 EXPECT_EQ(0L, p);
151 }
152
153 } // namespace __tsan