<commit_before>//===-- asan_interface_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 AddressSanitizer, an address sanity checker.
//
//===----------------------------------------------------------------------===//
#include "asan_test_utils.h"
#include <sanitizer/allocator_interface.h>
#include <sanitizer/asan_interface.h>

TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
  EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
  const size_t sizes[] = { 1, 30, 1<<30 };
  for (size_t i = 0; i < 3; i++) {
    EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
  }
}

static const char* kGetAllocatedSizeErrorMsg =
  "attempting to call __sanitizer_get_allocated_size";

TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
  const size_t kArraySize = 100;
  char *array = Ident((char*)malloc(kArraySize));
  int *int_ptr = Ident(new int);

  // Allocated memory is owned by allocator. Allocated size should be
  // equal to requested size.
  EXPECT_EQ(true, __sanitizer_get_ownership(array));
  EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
  EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
  EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));

  // We cannot call GetAllocatedSize from the memory we didn't map,
  // and from the interior pointers (not returned by previous malloc).
  void *wild_addr = (void*)0x1;
  EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
  EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
               kGetAllocatedSizeErrorMsg);
  EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
  EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
               kGetAllocatedSizeErrorMsg);

  // NULL is not owned, but is a valid argument for
  // __sanitizer_get_allocated_size().
  EXPECT_FALSE(__sanitizer_get_ownership(NULL));
  EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));

  // When memory is freed, it's not owned, and call to GetAllocatedSize
  // is forbidden.
  free(array);
  EXPECT_FALSE(__sanitizer_get_ownership(array));
  EXPECT_DEATH(__sanitizer_get_allocated_size(array),
               kGetAllocatedSizeErrorMsg);
  delete int_ptr;

  void *zero_alloc = Ident(malloc(0));
  if (zero_alloc != 0) {
    // If malloc(0) is not null, this pointer is owned and should have valid
    // allocated size.
    EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
    // Allocated size is 0 or 1 depending on the allocator used.
    EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
  }
  free(zero_alloc);
}

TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
  size_t before_malloc, after_malloc, after_free;
  char *array;
  const size_t kMallocSize = 100;
  before_malloc = __sanitizer_get_current_allocated_bytes();

  array = Ident((char*)malloc(kMallocSize));
  after_malloc = __sanitizer_get_current_allocated_bytes();
  EXPECT_EQ(before_malloc + kMallocSize, after_malloc);

  free(array);
  after_free = __sanitizer_get_current_allocated_bytes();
  EXPECT_EQ(before_malloc, after_free);
}

TEST(AddressSanitizerInterface, GetHeapSizeTest) {
  // ASan allocator does not keep huge chunks in free list, but unmaps them.
  // The chunk should be greater than the quarantine size,
  // otherwise it will be stuck in quarantine instead of being unmaped.
  static const size_t kLargeMallocSize = (1 << 28) + 1;  // 256M
  free(Ident(malloc(kLargeMallocSize)));  // Drain quarantine.
  size_t old_heap_size = __sanitizer_get_heap_size();
  for (int i = 0; i < 3; i++) {
    // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
    free(Ident(malloc(kLargeMallocSize)));
    EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
  }
}

static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
static const size_t kManyThreadsIterations = 250;
static const size_t kManyThreadsNumThreads =
  (SANITIZER_WORDSIZE == 32) ? 40 : 200;

static void *ManyThreadsWithStatsWorker(void *arg) {
  (void)arg;
  for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
    for (size_t size_index = 0; size_index < 4; size_index++) {
      free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
    }
  }
  // Just one large allocation.
  free(Ident(malloc(1 << 20)));
  return 0;
}

#ifndef __powerpc64__
// FIXME: This has not reliably worked on powerpc since r279664.  Re-enable
// this once the problem is tracked down and fixed.
TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
  size_t before_test, after_test, i;
  pthread_t threads[kManyThreadsNumThreads];<commit_msg>[powerpc] Move #if to appease warnings-as-errors tests<commit_after>//===-- asan_interface_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 AddressSanitizer, an address sanity checker.
//
//===----------------------------------------------------------------------===//
#include "asan_test_utils.h"
#include <sanitizer/allocator_interface.h>
#include <sanitizer/asan_interface.h>

TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
  EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
  const size_t sizes[] = { 1, 30, 1<<30 };
  for (size_t i = 0; i < 3; i++) {
    EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
  }
}

static const char* kGetAllocatedSizeErrorMsg =
  "attempting to call __sanitizer_get_allocated_size";

TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
  const size_t kArraySize = 100;
  char *array = Ident((char*)malloc(kArraySize));
  int *int_ptr = Ident(new int);

  // Allocated memory is owned by allocator. Allocated size should be
  // equal to requested size.
  EXPECT_EQ(true, __sanitizer_get_ownership(array));
  EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
  EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
  EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));

  // We cannot call GetAllocatedSize from the memory we didn't map,
  // and from the interior pointers (not returned by previous malloc).
  void *wild_addr = (void*)0x1;
  EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
  EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
               kGetAllocatedSizeErrorMsg);
  EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
  EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
               kGetAllocatedSizeErrorMsg);

  // NULL is not owned, but is a valid argument for
  // __sanitizer_get_allocated_size().
  EXPECT_FALSE(__sanitizer_get_ownership(NULL));
  EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));

  // When memory is freed, it's not owned, and call to GetAllocatedSize
  // is forbidden.
  free(array);
  EXPECT_FALSE(__sanitizer_get_ownership(array));
  EXPECT_DEATH(__sanitizer_get_allocated_size(array),
               kGetAllocatedSizeErrorMsg);
  delete int_ptr;

  void *zero_alloc = Ident(malloc(0));
  if (zero_alloc != 0) {
    // If malloc(0) is not null, this pointer is owned and should have valid
    // allocated size.
    EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
    // Allocated size is 0 or 1 depending on the allocator used.
    EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
  }
  free(zero_alloc);
}

TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
  size_t before_malloc, after_malloc, after_free;
  char *array;
  const size_t kMallocSize = 100;
  before_malloc = __sanitizer_get_current_allocated_bytes();

  array = Ident((char*)malloc(kMallocSize));
  after_malloc = __sanitizer_get_current_allocated_bytes();
  EXPECT_EQ(before_malloc + kMallocSize, after_malloc);

  free(array);
  after_free = __sanitizer_get_current_allocated_bytes();
  EXPECT_EQ(before_malloc, after_free);
}

TEST(AddressSanitizerInterface, GetHeapSizeTest) {
  // ASan allocator does not keep huge chunks in free list, but unmaps them.
  // The chunk should be greater than the quarantine size,
  // otherwise it will be stuck in quarantine instead of being unmaped.
  static const size_t kLargeMallocSize = (1 << 28) + 1;  // 256M
  free(Ident(malloc(kLargeMallocSize)));  // Drain quarantine.
  size_t old_heap_size = __sanitizer_get_heap_size();
  for (int i = 0; i < 3; i++) {
    // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
    free(Ident(malloc(kLargeMallocSize)));
    EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
  }
}

static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
static const size_t kManyThreadsIterations = 250;

#ifndef __powerpc64__
// FIXME: This has not reliably worked on powerpc since r279664.  Re-enable
// this once the problem is tracked down and fixed.
static const size_t kManyThreadsNumThreads =
  (SANITIZER_WORDSIZE == 32) ? 40 : 200;

static void *ManyThreadsWithStatsWorker(void *arg) {
  (void)arg;
  for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
    for (size_t size_index = 0; size_index < 4; size_index++) {
      free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
    }
  }
  // Just one large allocation.
  free(Ident(malloc(1 << 20)));
  return 0;
}

TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
  size_t before_test, after_test, i;
  pthread_t threads[kManyThreadsNumThreads];
{'fraction_non_alphanumeric': 0.1401499797324686, 'fraction_numerical': 0.014389947304418322, 'mean_word_length': 3.8953373015873014, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1770842', 'n_tokens_mistral': 3347, 'n_tokens_neox': 3231, 'n_words': 751}