LCOV - code coverage report
Current view: top level - test/unittests/base/platform - platform-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 70 72 97.2 %
Date: 2017-10-20 Functions: 16 22 72.7 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/base/platform/platform.h"
       6             : 
       7             : #if V8_OS_POSIX
       8             : #include <setjmp.h>
       9             : #include <signal.h>
      10             : #include <unistd.h>  // NOLINT
      11             : #endif
      12             : 
      13             : #if V8_OS_WIN
      14             : #include "src/base/win32-headers.h"
      15             : #endif
      16             : #include "testing/gtest/include/gtest/gtest.h"
      17             : 
      18             : #if V8_OS_ANDROID
      19             : #define DISABLE_ON_ANDROID(Name) DISABLED_##Name
      20             : #else
      21             : #define DISABLE_ON_ANDROID(Name) Name
      22             : #endif
      23             : 
      24             : namespace v8 {
      25             : namespace base {
      26             : 
      27       13158 : TEST(OS, GetCurrentProcessId) {
      28             : #if V8_OS_POSIX
      29           2 :   EXPECT_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
      30             : #endif
      31             : 
      32             : #if V8_OS_WIN
      33             :   EXPECT_EQ(static_cast<int>(::GetCurrentProcessId()),
      34             :             OS::GetCurrentProcessId());
      35             : #endif
      36           1 : }
      37             : 
      38             : 
      39             : namespace {
      40             : 
      41             : class ThreadLocalStorageTest : public Thread, public ::testing::Test {
      42             :  public:
      43           2 :   ThreadLocalStorageTest() : Thread(Options("ThreadLocalStorageTest")) {
      44          33 :     for (size_t i = 0; i < arraysize(keys_); ++i) {
      45          32 :       keys_[i] = Thread::CreateThreadLocalKey();
      46             :     }
      47           1 :   }
      48           2 :   ~ThreadLocalStorageTest() {
      49          33 :     for (size_t i = 0; i < arraysize(keys_); ++i) {
      50          32 :       Thread::DeleteThreadLocalKey(keys_[i]);
      51             :     }
      52           1 :   }
      53             : 
      54           2 :   void Run() final {
      55          66 :     for (size_t i = 0; i < arraysize(keys_); i++) {
      56         128 :       CHECK(!Thread::HasThreadLocal(keys_[i]));
      57             :     }
      58          66 :     for (size_t i = 0; i < arraysize(keys_); i++) {
      59          64 :       Thread::SetThreadLocal(keys_[i], GetValue(i));
      60             :     }
      61          64 :     for (size_t i = 0; i < arraysize(keys_); i++) {
      62         128 :       CHECK(Thread::HasThreadLocal(keys_[i]));
      63             :     }
      64          66 :     for (size_t i = 0; i < arraysize(keys_); i++) {
      65         128 :       CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys_[i]));
      66         128 :       CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys_[i]));
      67             :     }
      68          64 :     for (size_t i = 0; i < arraysize(keys_); i++) {
      69          64 :       Thread::SetThreadLocal(keys_[i], GetValue(arraysize(keys_) - i - 1));
      70             :     }
      71          64 :     for (size_t i = 0; i < arraysize(keys_); i++) {
      72         128 :       CHECK(Thread::HasThreadLocal(keys_[i]));
      73             :     }
      74          64 :     for (size_t i = 0; i < arraysize(keys_); i++) {
      75         128 :       CHECK_EQ(GetValue(arraysize(keys_) - i - 1),
      76             :                Thread::GetThreadLocal(keys_[i]));
      77         128 :       CHECK_EQ(GetValue(arraysize(keys_) - i - 1),
      78             :                Thread::GetExistingThreadLocal(keys_[i]));
      79             :     }
      80           2 :   }
      81             : 
      82             :  private:
      83             :   static void* GetValue(size_t x) {
      84         256 :     return bit_cast<void*>(static_cast<uintptr_t>(x + 1));
      85             :   }
      86             : 
      87             :   // Older versions of Android have fewer TLS slots (nominally 64, but the
      88             :   // system uses "about 5 of them" itself).
      89             :   Thread::LocalStorageKey keys_[32];
      90             : };
      91             : 
      92             : }  // namespace
      93             : 
      94             : 
      95       13158 : TEST_F(ThreadLocalStorageTest, DoTest) {
      96           1 :   Run();
      97           1 :   Start();
      98           1 :   Join();
      99           1 : }
     100             : 
     101             : #if V8_OS_POSIX
     102             : // TODO(eholk): Add a windows version of these tests
     103             : 
     104             : namespace {
     105             : 
     106             : // These tests make sure the routines to allocate memory do so with the correct
     107             : // permissions.
     108             : //
     109             : // Unfortunately, there is no API to find the protection of a memory address,
     110             : // so instead we test permissions by installing a signal handler, probing a
     111             : // memory location and recovering from the fault.
     112             : //
     113             : // We don't test the execution permission because to do so we'd have to
     114             : // dynamically generate code and test if we can execute it.
     115             : 
     116           2 : class MemoryAllocationPermissionsTest : public ::testing::Test {
     117           2 :   static void SignalHandler(int signal, siginfo_t* info, void*) {
     118           2 :     siglongjmp(continuation_, 1);
     119             :   }
     120             :   struct sigaction old_action_;
     121             : // On Mac, sometimes we get SIGBUS instead of SIGSEGV.
     122             : #if V8_OS_MACOSX
     123             :   struct sigaction old_bus_action_;
     124             : #endif
     125             : 
     126             :  protected:
     127           1 :   virtual void SetUp() {
     128             :     struct sigaction action;
     129           1 :     action.sa_sigaction = SignalHandler;
     130           1 :     sigemptyset(&action.sa_mask);
     131           1 :     action.sa_flags = SA_SIGINFO;
     132           1 :     sigaction(SIGSEGV, &action, &old_action_);
     133             : #if V8_OS_MACOSX
     134             :     sigaction(SIGBUS, &action, &old_bus_action_);
     135             : #endif
     136           1 :   }
     137             : 
     138           1 :   virtual void TearDown() {
     139             :     // be a good citizen and restore the old signal handler.
     140           1 :     sigaction(SIGSEGV, &old_action_, nullptr);
     141             : #if V8_OS_MACOSX
     142             :     sigaction(SIGBUS, &old_bus_action_, nullptr);
     143             : #endif
     144           1 :   }
     145             : 
     146             :  public:
     147             :   static sigjmp_buf continuation_;
     148             : 
     149             :   enum class MemoryAction { kRead, kWrite };
     150             : 
     151           6 :   void ProbeMemory(volatile int* buffer, MemoryAction action,
     152             :                    bool should_succeed) {
     153             :     const int save_sigs = 1;
     154           6 :     if (!sigsetjmp(continuation_, save_sigs)) {
     155           4 :       switch (action) {
     156             :         case MemoryAction::kRead: {
     157             :           // static_cast to remove the reference and force a memory read.
     158           2 :           USE(static_cast<int>(*buffer));
     159             :           break;
     160             :         }
     161             :         case MemoryAction::kWrite: {
     162           2 :           *buffer = 0;
     163             :           break;
     164             :         }
     165             :       }
     166           4 :       if (should_succeed) {
     167           8 :         SUCCEED();
     168             :       } else {
     169           0 :         FAIL();
     170             :       }
     171             :       return;
     172             :     }
     173           2 :     if (should_succeed) {
     174           0 :       FAIL();
     175             :     } else {
     176           4 :       SUCCEED();
     177             :     }
     178             :   }
     179             : 
     180           3 :   void TestPermissions(OS::MemoryPermission permission, bool can_read,
     181             :                        bool can_write) {
     182           3 :     const size_t allocation_size = OS::CommitPageSize();
     183           3 :     size_t actual = 0;
     184             :     int* buffer =
     185           3 :         static_cast<int*>(OS::Allocate(allocation_size, &actual, permission));
     186           3 :     ProbeMemory(buffer, MemoryAction::kRead, can_read);
     187           3 :     ProbeMemory(buffer, MemoryAction::kWrite, can_write);
     188           3 :     OS::Free(buffer, actual);
     189           3 :   }
     190             : };
     191             : 
     192             : sigjmp_buf MemoryAllocationPermissionsTest::continuation_;
     193             : 
     194       13159 : TEST_F(MemoryAllocationPermissionsTest, DoTest) {
     195           1 :   TestPermissions(OS::MemoryPermission::kNoAccess, false, false);
     196           1 :   TestPermissions(OS::MemoryPermission::kReadWrite, true, true);
     197           1 :   TestPermissions(OS::MemoryPermission::kReadWriteExecute, true, true);
     198           1 : }
     199             : 
     200             : }  // namespace
     201             : #endif  // V8_OS_POSIX
     202             : 
     203             : }  // namespace base
     204        7893 : }  // namespace v8

Generated by: LCOV version 1.10