197 lines · cpp
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-exception6//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 return56 // 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(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 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_DEBUG158// 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 by169 // 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#endif177 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 __tsan197