• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TEST(Mman,Internal)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 
TEST(Mman,User)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 
TEST(Mman,UserRealloc)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 
TEST(Mman,UsableSize)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 
TEST(Mman,Stats)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 
TEST(Mman,CallocOverflow)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
154