brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · c18e5bd Raw
139 lines · cpp
1//===-- sanitizer_procmaps_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/AddressSanitizer runtime.10//11//===----------------------------------------------------------------------===//12#if !defined(_WIN32)  // There are no /proc/maps on Windows.13 14#  include "sanitizer_common/sanitizer_procmaps.h"15 16#  include <stdlib.h>17#  include <string.h>18 19#  include <vector>20 21#  include "gtest/gtest.h"22 23static void noop() {}24extern const char *argv0;25 26namespace __sanitizer {27 28#  if SANITIZER_LINUX && !SANITIZER_ANDROID29TEST(MemoryMappingLayout, CodeRange) {30  uptr start, end;31  bool res = GetCodeRangeForFile("[vdso]", &start, &end);32  EXPECT_EQ(res, true);33  EXPECT_GT(start, 0U);34  EXPECT_LT(start, end);35}36#  endif37 38TEST(MemoryMappingLayout, DumpListOfModules) {39  const char *last_slash = strrchr(argv0, '/');40  const char *binary_name = last_slash ? last_slash + 1 : argv0;41  MemoryMappingLayout memory_mapping(false);42  const uptr kMaxModules = 100;43  InternalMmapVector<LoadedModule> modules;44  modules.reserve(kMaxModules);45  memory_mapping.DumpListOfModules(&modules);46  EXPECT_GT(modules.size(), 0U);47  bool found = false;48  for (uptr i = 0; i < modules.size(); ++i) {49    if (modules[i].containsAddress((uptr)&noop)) {50      // Verify that the module name is sane.51      if (strstr(modules[i].full_name(), binary_name) != 0)52        found = true;53    }54    modules[i].clear();55  }56  EXPECT_TRUE(found);57}58 59TEST(MemoryMapping, LoadedModuleArchAndUUID) {60  if (SANITIZER_APPLE) {61    MemoryMappingLayout memory_mapping(false);62    const uptr kMaxModules = 100;63    InternalMmapVector<LoadedModule> modules;64    modules.reserve(kMaxModules);65    memory_mapping.DumpListOfModules(&modules);66    for (uptr i = 0; i < modules.size(); ++i) {67      ModuleArch arch = modules[i].arch();68      // Darwin unit tests are only run on i386/x86_64/x86_64h/arm64.69      if (SANITIZER_WORDSIZE == 32) {70        EXPECT_EQ(arch, kModuleArchI386);71      } else if (SANITIZER_WORDSIZE == 64) {72        EXPECT_TRUE(arch == kModuleArchX86_64 || arch == kModuleArchX86_64H ||73                    arch == kModuleArchARM64 || arch == kModuleArchARM64E);74      }75      const u8 *uuid = modules[i].uuid();76      u8 null_uuid[kModuleUUIDSize] = {0};77      EXPECT_NE(memcmp(null_uuid, uuid, kModuleUUIDSize), 0);78    }79  }80}81 82#  if (SANITIZER_LINUX || SANITIZER_NETBSD || SANITIZER_SOLARIS) && \83      defined(_LP64)84const char *const parse_unix_input = R"(857fb9862f1000-7fb9862f3000 rw-p 00000000 00:00 0 86Size:                  8 kB87Rss:                   4 kB887fb9864ae000-7fb9864b1000 r--p 001ba000 fd:01 22413919                   /lib/x86_64-linux-gnu/libc-2.32.so89Size:                 12 kB90Rss:                  12 kB91)";92 93TEST(MemoryMapping, ParseUnixMemoryProfile) {94  struct entry {95    uptr p;96    uptr rss;97    bool file;98  };99  typedef std::vector<entry> entries_t;100  entries_t entries;101  std::vector<char> input(parse_unix_input,102                          parse_unix_input + strlen(parse_unix_input));103  ParseUnixMemoryProfile(104      [](uptr p, uptr rss, bool file, uptr *mem) {105        reinterpret_cast<entries_t *>(mem)->push_back({p, rss, file});106      },107      reinterpret_cast<uptr *>(&entries), &input[0], input.size());108  EXPECT_EQ(entries.size(), 2ul);109  EXPECT_EQ(entries[0].p, 0x7fb9862f1000ul);110  EXPECT_EQ(entries[0].rss, 4ul << 10);111  EXPECT_EQ(entries[0].file, false);112  EXPECT_EQ(entries[1].p, 0x7fb9864ae000ul);113  EXPECT_EQ(entries[1].rss, 12ul << 10);114  EXPECT_EQ(entries[1].file, true);115}116 117TEST(MemoryMapping, ParseUnixMemoryProfileTruncated) {118  // ParseUnixMemoryProfile used to crash on truncated inputs.119  // This test allocates 2 pages, protects the second one120  // and places the input at the very end of the first page121  // to test for over-reads.122  uptr page = GetPageSizeCached();123  char *mem = static_cast<char *>(124      MmapOrDie(2 * page, "ParseUnixMemoryProfileTruncated"));125  EXPECT_TRUE(MprotectNoAccess(reinterpret_cast<uptr>(mem + page), page));126  const uptr len = strlen(parse_unix_input);127  for (uptr i = 0; i < len; i++) {128    char *smaps = mem + page - len + i;129    memcpy(smaps, parse_unix_input, len - i);130    ParseUnixMemoryProfile([](uptr p, uptr rss, bool file, uptr *mem) {},131                           nullptr, smaps, len - i);132  }133  UnmapOrDie(mem, 2 * page);134}135#  endif136 137}  // namespace __sanitizer138#endif  // !defined(_WIN32)139