1 //===-- asan_noinst_test.cc ------------*- C++ -*-===// 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 AddressSanitizer, an address sanity checker. 11 // 12 // This test file should be compiled w/o asan instrumentation. 13 //===----------------------------------------------------------------------===// 14 #include "asan_allocator.h" 15 #include "asan_interface.h" 16 #include "asan_internal.h" 17 #include "asan_mapping.h" 18 #include "asan_stack.h" 19 #include "asan_test_utils.h" 20 21 #include <assert.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <vector> 25 #include <algorithm> 26 #include "gtest/gtest.h" 27 28 // Simple stand-alone pseudorandom number generator. 29 // Current algorithm is ANSI C linear congruential PRNG. 30 static inline uint32_t my_rand(uint32_t* state) { 31 return (*state = *state * 1103515245 + 12345) >> 16; 32 } 33 34 static uint32_t global_seed = 0; 35 36 37 TEST(AddressSanitizer, InternalSimpleDeathTest) { 38 EXPECT_DEATH(exit(1), ""); 39 } 40 41 static void MallocStress(size_t n) { 42 uint32_t seed = my_rand(&global_seed); 43 __asan::AsanStackTrace stack1; 44 stack1.trace[0] = 0xa123; 45 stack1.trace[1] = 0xa456; 46 stack1.size = 2; 47 48 __asan::AsanStackTrace stack2; 49 stack2.trace[0] = 0xb123; 50 stack2.trace[1] = 0xb456; 51 stack2.size = 2; 52 53 __asan::AsanStackTrace stack3; 54 stack3.trace[0] = 0xc123; 55 stack3.trace[1] = 0xc456; 56 stack3.size = 2; 57 58 std::vector<void *> vec; 59 for (size_t i = 0; i < n; i++) { 60 if ((i % 3) == 0) { 61 if (vec.empty()) continue; 62 size_t idx = my_rand(&seed) % vec.size(); 63 void *ptr = vec[idx]; 64 vec[idx] = vec.back(); 65 vec.pop_back(); 66 __asan::asan_free(ptr, &stack1); 67 } else { 68 size_t size = my_rand(&seed) % 1000 + 1; 69 switch ((my_rand(&seed) % 128)) { 70 case 0: size += 1024; break; 71 case 1: size += 2048; break; 72 case 2: size += 4096; break; 73 } 74 size_t alignment = 1 << (my_rand(&seed) % 10 + 1); 75 char *ptr = (char*)__asan::asan_memalign(alignment, size, &stack2); 76 vec.push_back(ptr); 77 ptr[0] = 0; 78 ptr[size-1] = 0; 79 ptr[size/2] = 0; 80 } 81 } 82 for (size_t i = 0; i < vec.size(); i++) 83 __asan::asan_free(vec[i], &stack3); 84 } 85 86 87 TEST(AddressSanitizer, NoInstMallocTest) { 88 #ifdef __arm__ 89 MallocStress(300000); 90 #else 91 MallocStress(1000000); 92 #endif 93 } 94 95 static void PrintShadow(const char *tag, uintptr_t ptr, size_t size) { 96 fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size); 97 uintptr_t prev_shadow = 0; 98 for (intptr_t i = -32; i < (intptr_t)size + 32; i++) { 99 uintptr_t shadow = __asan::MemToShadow(ptr + i); 100 if (i == 0 || i == (intptr_t)size) 101 fprintf(stderr, "."); 102 if (shadow != prev_shadow) { 103 prev_shadow = shadow; 104 fprintf(stderr, "%02x", (int)*(uint8_t*)shadow); 105 } 106 } 107 fprintf(stderr, "\n"); 108 } 109 110 TEST(AddressSanitizer, DISABLED_InternalPrintShadow) { 111 for (size_t size = 1; size <= 513; size++) { 112 char *ptr = new char[size]; 113 PrintShadow("m", (uintptr_t)ptr, size); 114 delete [] ptr; 115 PrintShadow("f", (uintptr_t)ptr, size); 116 } 117 } 118 119 static uintptr_t pc_array[] = { 120 #if __WORDSIZE == 64 121 0x7effbf756068ULL, 122 0x7effbf75e5abULL, 123 0x7effc0625b7cULL, 124 0x7effc05b8997ULL, 125 0x7effbf990577ULL, 126 0x7effbf990c56ULL, 127 0x7effbf992f3cULL, 128 0x7effbf950c22ULL, 129 0x7effc036dba0ULL, 130 0x7effc03638a3ULL, 131 0x7effc035be4aULL, 132 0x7effc0539c45ULL, 133 0x7effc0539a65ULL, 134 0x7effc03db9b3ULL, 135 0x7effc03db100ULL, 136 0x7effc037c7b8ULL, 137 0x7effc037bfffULL, 138 0x7effc038b777ULL, 139 0x7effc038021cULL, 140 0x7effc037c7d1ULL, 141 0x7effc037bfffULL, 142 0x7effc038b777ULL, 143 0x7effc038021cULL, 144 0x7effc037c7d1ULL, 145 0x7effc037bfffULL, 146 0x7effc038b777ULL, 147 0x7effc038021cULL, 148 0x7effc037c7d1ULL, 149 0x7effc037bfffULL, 150 0x7effc0520d26ULL, 151 0x7effc009ddffULL, 152 0x7effbf90bb50ULL, 153 0x7effbdddfa69ULL, 154 0x7effbdde1fe2ULL, 155 0x7effbdde2424ULL, 156 0x7effbdde27b3ULL, 157 0x7effbddee53bULL, 158 0x7effbdde1988ULL, 159 0x7effbdde0904ULL, 160 0x7effc106ce0dULL, 161 0x7effbcc3fa04ULL, 162 0x7effbcc3f6a4ULL, 163 0x7effbcc3e726ULL, 164 0x7effbcc40852ULL, 165 0x7effb681ec4dULL, 166 #endif // __WORDSIZE 167 0xB0B5E768, 168 0x7B682EC1, 169 0x367F9918, 170 0xAE34E13, 171 0xBA0C6C6, 172 0x13250F46, 173 0xA0D6A8AB, 174 0x2B07C1A8, 175 0x6C844F4A, 176 0x2321B53, 177 0x1F3D4F8F, 178 0x3FE2924B, 179 0xB7A2F568, 180 0xBD23950A, 181 0x61020930, 182 0x33E7970C, 183 0x405998A1, 184 0x59F3551D, 185 0x350E3028, 186 0xBC55A28D, 187 0x361F3AED, 188 0xBEAD0F73, 189 0xAEF28479, 190 0x757E971F, 191 0xAEBA450, 192 0x43AD22F5, 193 0x8C2C50C4, 194 0x7AD8A2E1, 195 0x69EE4EE8, 196 0xC08DFF, 197 0x4BA6538, 198 0x3708AB2, 199 0xC24B6475, 200 0x7C8890D7, 201 0x6662495F, 202 0x9B641689, 203 0xD3596B, 204 0xA1049569, 205 0x44CBC16, 206 0x4D39C39F 207 }; 208 209 void CompressStackTraceTest(size_t n_iter) { 210 uint32_t seed = my_rand(&global_seed); 211 const size_t kNumPcs = ASAN_ARRAY_SIZE(pc_array); 212 uint32_t compressed[2 * kNumPcs]; 213 214 for (size_t iter = 0; iter < n_iter; iter++) { 215 std::random_shuffle(pc_array, pc_array + kNumPcs); 216 __asan::AsanStackTrace stack0, stack1; 217 stack0.CopyFrom(pc_array, kNumPcs); 218 stack0.size = std::max((size_t)1, (size_t)my_rand(&seed) % stack0.size); 219 size_t compress_size = 220 std::max((size_t)2, (size_t)my_rand(&seed) % (2 * kNumPcs)); 221 size_t n_frames = 222 __asan::AsanStackTrace::CompressStack(&stack0, compressed, compress_size); 223 assert(n_frames <= stack0.size); 224 __asan::AsanStackTrace::UncompressStack(&stack1, compressed, compress_size); 225 assert(stack1.size == n_frames); 226 for (size_t i = 0; i < stack1.size; i++) { 227 assert(stack0.trace[i] == stack1.trace[i]); 228 } 229 } 230 } 231 232 TEST(AddressSanitizer, CompressStackTraceTest) { 233 CompressStackTraceTest(10000); 234 } 235 236 void CompressStackTraceBenchmark(size_t n_iter) { 237 const size_t kNumPcs = ASAN_ARRAY_SIZE(pc_array); 238 uint32_t compressed[2 * kNumPcs]; 239 std::random_shuffle(pc_array, pc_array + kNumPcs); 240 241 __asan::AsanStackTrace stack0; 242 stack0.CopyFrom(pc_array, kNumPcs); 243 stack0.size = kNumPcs; 244 for (size_t iter = 0; iter < n_iter; iter++) { 245 size_t compress_size = kNumPcs; 246 size_t n_frames = 247 __asan::AsanStackTrace::CompressStack(&stack0, compressed, compress_size); 248 Ident(n_frames); 249 } 250 } 251 252 TEST(AddressSanitizer, CompressStackTraceBenchmark) { 253 CompressStackTraceBenchmark(1 << 24); 254 } 255 256 TEST(AddressSanitizer, QuarantineTest) { 257 __asan::AsanStackTrace stack; 258 stack.trace[0] = 0x890; 259 stack.size = 1; 260 261 const int size = 32; 262 void *p = __asan::asan_malloc(size, &stack); 263 __asan::asan_free(p, &stack); 264 size_t i; 265 size_t max_i = 1 << 30; 266 for (i = 0; i < max_i; i++) { 267 void *p1 = __asan::asan_malloc(size, &stack); 268 __asan::asan_free(p1, &stack); 269 if (p1 == p) break; 270 } 271 // fprintf(stderr, "i=%ld\n", i); 272 EXPECT_GE(i, 100000U); 273 EXPECT_LT(i, max_i); 274 } 275 276 void *ThreadedQuarantineTestWorker(void *unused) { 277 uint32_t seed = my_rand(&global_seed); 278 __asan::AsanStackTrace stack; 279 stack.trace[0] = 0x890; 280 stack.size = 1; 281 282 for (size_t i = 0; i < 1000; i++) { 283 void *p = __asan::asan_malloc(1 + (my_rand(&seed) % 4000), &stack); 284 __asan::asan_free(p, &stack); 285 } 286 return NULL; 287 } 288 289 // Check that the thread local allocators are flushed when threads are 290 // destroyed. 291 TEST(AddressSanitizer, ThreadedQuarantineTest) { 292 const int n_threads = 3000; 293 size_t mmaped1 = __asan_get_heap_size(); 294 for (int i = 0; i < n_threads; i++) { 295 pthread_t t; 296 pthread_create(&t, NULL, ThreadedQuarantineTestWorker, 0); 297 pthread_join(t, 0); 298 size_t mmaped2 = __asan_get_heap_size(); 299 EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20)); 300 } 301 } 302 303 void *ThreadedOneSizeMallocStress(void *unused) { 304 __asan::AsanStackTrace stack; 305 stack.trace[0] = 0x890; 306 stack.size = 1; 307 const size_t kNumMallocs = 1000; 308 for (int iter = 0; iter < 1000; iter++) { 309 void *p[kNumMallocs]; 310 for (size_t i = 0; i < kNumMallocs; i++) { 311 p[i] = __asan::asan_malloc(32, &stack); 312 } 313 for (size_t i = 0; i < kNumMallocs; i++) { 314 __asan::asan_free(p[i], &stack); 315 } 316 } 317 return NULL; 318 } 319 320 TEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) { 321 const int kNumThreads = 4; 322 pthread_t t[kNumThreads]; 323 for (int i = 0; i < kNumThreads; i++) { 324 pthread_create(&t[i], 0, ThreadedOneSizeMallocStress, 0); 325 } 326 for (int i = 0; i < kNumThreads; i++) { 327 pthread_join(t[i], 0); 328 } 329 } 330