aboutsummaryrefslogtreecommitdiff
path: root/lib/tsan/unit_tests/tsan_mman_test.cc
blob: 1a9a88f606fcc4da6ffc89079b44579b7376cbab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//===-- tsan_mman_test.cc -------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
//===----------------------------------------------------------------------===//
#include "tsan_mman.h"
#include "tsan_rtl.h"
#include "gtest/gtest.h"

namespace __tsan {

TEST(Mman, Internal) {
  ScopedInRtl in_rtl;
  char *p = (char*)internal_alloc(MBlockScopedBuf, 10);
  EXPECT_NE(p, (char*)0);
  char *p2 = (char*)internal_alloc(MBlockScopedBuf, 20);
  EXPECT_NE(p2, (char*)0);
  EXPECT_NE(p2, p);
  for (int i = 0; i < 10; i++) {
    p[i] = 42;
  }
  for (int i = 0; i < 20; i++) {
    ((char*)p2)[i] = 42;
  }
  internal_free(p);
  internal_free(p2);
}

TEST(Mman, User) {
  ScopedInRtl in_rtl;
  ThreadState *thr = cur_thread();
  uptr pc = 0;
  char *p = (char*)user_alloc(thr, pc, 10);
  EXPECT_NE(p, (char*)0);
  char *p2 = (char*)user_alloc(thr, pc, 20);
  EXPECT_NE(p2, (char*)0);
  EXPECT_NE(p2, p);
  MBlock *b = user_mblock(thr, p);
  EXPECT_NE(b, (MBlock*)0);
  EXPECT_EQ(b->size, (uptr)10);
  MBlock *b2 = user_mblock(thr, p2);
  EXPECT_NE(b2, (MBlock*)0);
  EXPECT_EQ(b2->size, (uptr)20);
  for (int i = 0; i < 10; i++) {
    p[i] = 42;
    EXPECT_EQ(b, user_mblock(thr, p + i));
  }
  for (int i = 0; i < 20; i++) {
    ((char*)p2)[i] = 42;
    EXPECT_EQ(b2, user_mblock(thr, p2 + i));
  }
  user_free(thr, pc, p);
  user_free(thr, pc, p2);
}

TEST(Mman, UserRealloc) {
  ScopedInRtl in_rtl;
  ThreadState *thr = cur_thread();
  uptr pc = 0;
  {
    void *p = user_realloc(thr, pc, 0, 0);
    // Strictly saying this is incorrect, realloc(NULL, N) is equivalent to
    // malloc(N), thus must return non-NULL pointer.
    EXPECT_EQ(p, (void*)0);
  }
  {
    void *p = user_realloc(thr, pc, 0, 100);
    EXPECT_NE(p, (void*)0);
    memset(p, 0xde, 100);
    user_free(thr, pc, p);
  }
  {
    void *p = user_alloc(thr, pc, 100);
    EXPECT_NE(p, (void*)0);
    memset(p, 0xde, 100);
    void *p2 = user_realloc(thr, pc, p, 0);
    EXPECT_EQ(p2, (void*)0);
  }
  {
    void *p = user_realloc(thr, pc, 0, 100);
    EXPECT_NE(p, (void*)0);
    memset(p, 0xde, 100);
    void *p2 = user_realloc(thr, pc, p, 10000);
    EXPECT_NE(p2, (void*)0);
    for (int i = 0; i < 100; i++)
      EXPECT_EQ(((char*)p2)[i], (char)0xde);
    memset(p2, 0xde, 10000);
    user_free(thr, pc, p2);
  }
  {
    void *p = user_realloc(thr, pc, 0, 10000);
    EXPECT_NE(p, (void*)0);
    memset(p, 0xde, 10000);
    void *p2 = user_realloc(thr, pc, p, 10);
    EXPECT_NE(p2, (void*)0);
    for (int i = 0; i < 10; i++)
      EXPECT_EQ(((char*)p2)[i], (char)0xde);
    user_free(thr, pc, p2);
  }
}

}  // namespace __tsan