Skip to content

Commit

Permalink
Add switch to always use temp dir in shared memory instances on Linux…
Browse files Browse the repository at this point in the history
… builds

Modify GetShmemTempDir to check for a runtime switch to always use the temp dir
Changes tests in shared_memory_unittest.cc to be parameterized and
test also for when /dev/shm is disabled.

Bug: 736452,792117
Change-Id: Id930ea525980e97c4ab70e37689301370776fc79
Reviewed-on: https://chromium-review.googlesource.com/810325
Reviewed-by: Robert Sesek <[email protected]>
Reviewed-by: Lei Zhang <[email protected]>
Commit-Queue: David Vallet <[email protected]>
Cr-Commit-Position: refs/heads/master@{#523959}
  • Loading branch information
David Vallet authored and Commit Bot committed Dec 14, 2017
1 parent 1050c3a commit 1824e57
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 18 deletions.
8 changes: 8 additions & 0 deletions base/base_switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ const char kProfilingFile[] = "profiling-file";
const char kDisableUsbKeyboardDetect[] = "disable-usb-keyboard-detect";
#endif

#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
// The /dev/shm partition is too small in certain VM environments, causing
// Chrome to fail or crash (see http://crbug.com/715363). Use this flag to
// work-around this issue (a temporary directory will always be used to create
// anonymous shared memory files).
const char kDisableDevShmUsage[] = "disable-dev-shm-usage";
#endif

#if defined(OS_POSIX)
// Used for turning on Breakpad crash reporting in a debug environment where
// crash reporting is typically compiled but disabled.
Expand Down
4 changes: 4 additions & 0 deletions base/base_switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ extern const char kWaitForDebugger[];
extern const char kDisableUsbKeyboardDetect[];
#endif

#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
extern const char kDisableDevShmUsage[];
#endif

#if defined(OS_POSIX)
extern const char kEnableCrashReporterForTesting[];
#endif
Expand Down
11 changes: 9 additions & 2 deletions base/files/file_util_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <time.h>
#include <unistd.h>

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/stack.h"
#include "base/environment.h"
#include "base/files/file_enumerator.h"
Expand Down Expand Up @@ -985,16 +987,21 @@ int GetMaximumPathComponentLength(const FilePath& path) {
// This is implemented in file_util_android.cc for that platform.
bool GetShmemTempDir(bool executable, FilePath* path) {
#if defined(OS_LINUX) || defined(OS_AIX)
bool disable_dev_shm = false;
#if !defined(OS_CHROMEOS)
disable_dev_shm = CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableDevShmUsage);
#endif
bool use_dev_shm = true;
if (executable) {
static const bool s_dev_shm_executable = DetermineDevShmExecutable();
use_dev_shm = s_dev_shm_executable;
}
if (use_dev_shm) {
if (use_dev_shm && !disable_dev_shm) {
*path = FilePath("/dev/shm");
return true;
}
#endif
#endif // defined(OS_LINUX) || defined(OS_AIX)
return GetTempDir(path);
}
#endif // !defined(OS_ANDROID)
Expand Down
67 changes: 51 additions & 16 deletions base/memory/shared_memory_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <memory>

#include "base/atomicops.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/shared_memory_handle.h"
#include "base/process/kill.h"
Expand Down Expand Up @@ -100,12 +102,36 @@ const char MultipleThreadMain::s_test_name_[] =
"SharedMemoryOpenThreadTest";
#endif // !defined(OS_MACOSX) && !defined(OS_FUCHSIA)

enum class Mode {
Default,
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
DisableDevShm = 1,
#endif
};

class SharedMemoryTest : public ::testing::TestWithParam<Mode> {
public:
void SetUp() override {
switch (GetParam()) {
case Mode::Default:
break;
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
case Mode::DisableDevShm:
CommandLine* cmdline = CommandLine::ForCurrentProcess();
cmdline->AppendSwitch(switches::kDisableDevShmUsage);
break;
#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
}
}
};

} // namespace

// Android/Mac/Fuchsia doesn't support SharedMemory::Open/Delete/
// CreateNamedDeprecated(openExisting=true)
#if !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
TEST(SharedMemoryTest, OpenClose) {

TEST_P(SharedMemoryTest, OpenClose) {
const uint32_t kDataSize = 1024;
std::string test_name = "SharedMemoryOpenCloseTest";

Expand Down Expand Up @@ -153,7 +179,7 @@ TEST(SharedMemoryTest, OpenClose) {
EXPECT_TRUE(rv);
}

TEST(SharedMemoryTest, OpenExclusive) {
TEST_P(SharedMemoryTest, OpenExclusive) {
const uint32_t kDataSize = 1024;
const uint32_t kDataSize2 = 2048;
std::ostringstream test_name_stream;
Expand Down Expand Up @@ -221,7 +247,7 @@ TEST(SharedMemoryTest, OpenExclusive) {
#endif // !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)

// Check that memory is still mapped after its closed.
TEST(SharedMemoryTest, CloseNoUnmap) {
TEST_P(SharedMemoryTest, CloseNoUnmap) {
const size_t kDataSize = 4096;

SharedMemory memory;
Expand All @@ -246,7 +272,7 @@ TEST(SharedMemoryTest, CloseNoUnmap) {
#if !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
// Create a set of N threads to each open a shared memory segment and write to
// it. Verify that they are always reading/writing consistent data.
TEST(SharedMemoryTest, MultipleThreads) {
TEST_P(SharedMemoryTest, MultipleThreads) {
const int kNumThreads = 5;

MultipleThreadMain::CleanUp();
Expand Down Expand Up @@ -287,7 +313,7 @@ TEST(SharedMemoryTest, MultipleThreads) {
// Allocate private (unique) shared memory with an empty string for a
// name. Make sure several of them don't point to the same thing as
// we might expect if the names are equal.
TEST(SharedMemoryTest, AnonymousPrivate) {
TEST_P(SharedMemoryTest, AnonymousPrivate) {
int i, j;
int count = 4;
bool rv;
Expand Down Expand Up @@ -328,7 +354,7 @@ TEST(SharedMemoryTest, AnonymousPrivate) {
}
}

TEST(SharedMemoryTest, GetReadOnlyHandle) {
TEST_P(SharedMemoryTest, GetReadOnlyHandle) {
StringPiece contents = "Hello World";

SharedMemory writable_shmem;
Expand Down Expand Up @@ -430,7 +456,7 @@ TEST(SharedMemoryTest, GetReadOnlyHandle) {
#endif // defined(OS_POSIX) || defined(OS_WIN)
}

TEST(SharedMemoryTest, ShareToSelf) {
TEST_P(SharedMemoryTest, ShareToSelf) {
StringPiece contents = "Hello World";

SharedMemory shmem;
Expand Down Expand Up @@ -461,7 +487,7 @@ TEST(SharedMemoryTest, ShareToSelf) {
contents.size()));
}

TEST(SharedMemoryTest, ShareWithMultipleInstances) {
TEST_P(SharedMemoryTest, ShareWithMultipleInstances) {
static const StringPiece kContents = "Hello World";

SharedMemory shmem;
Expand Down Expand Up @@ -505,7 +531,7 @@ TEST(SharedMemoryTest, ShareWithMultipleInstances) {
ASSERT_EQ(StringPiece(ToLowerASCII(kContents)), readonly_contents);
}

TEST(SharedMemoryTest, MapAt) {
TEST_P(SharedMemoryTest, MapAt) {
ASSERT_TRUE(SysInfo::VMAllocationGranularity() >= sizeof(uint32_t));
const size_t kCount = SysInfo::VMAllocationGranularity();
const size_t kDataSize = kCount * sizeof(uint32_t);
Expand All @@ -531,7 +557,7 @@ TEST(SharedMemoryTest, MapAt) {
}
}

TEST(SharedMemoryTest, MapTwice) {
TEST_P(SharedMemoryTest, MapTwice) {
const uint32_t kDataSize = 1024;
SharedMemory memory;
bool rv = memory.CreateAndMapAnonymous(kDataSize);
Expand All @@ -548,7 +574,7 @@ TEST(SharedMemoryTest, MapTwice) {
// This test is not applicable for iOS (crbug.com/399384).
#if !defined(OS_IOS)
// Create a shared memory object, mmap it, and mprotect it to PROT_EXEC.
TEST(SharedMemoryTest, AnonymousExecutable) {
TEST_P(SharedMemoryTest, AnonymousExecutable) {
const uint32_t kTestSize = 1 << 16;

SharedMemory shared_memory;
Expand Down Expand Up @@ -588,7 +614,7 @@ class ScopedUmaskSetter {
};

// Create a shared memory object, check its permissions.
TEST(SharedMemoryTest, FilePermissionsAnonymous) {
TEST_P(SharedMemoryTest, FilePermissionsAnonymous) {
const uint32_t kTestSize = 1 << 8;

SharedMemory shared_memory;
Expand All @@ -614,7 +640,7 @@ TEST(SharedMemoryTest, FilePermissionsAnonymous) {
}

// Create a shared memory object, check its permissions.
TEST(SharedMemoryTest, FilePermissionsNamed) {
TEST_P(SharedMemoryTest, FilePermissionsNamed) {
const uint32_t kTestSize = 1 << 8;

SharedMemory shared_memory;
Expand Down Expand Up @@ -645,7 +671,7 @@ TEST(SharedMemoryTest, FilePermissionsNamed) {
// Map() will return addresses which are aligned to the platform page size, this
// varies from platform to platform though. Since we'd like to advertise a
// minimum alignment that callers can count on, test for it here.
TEST(SharedMemoryTest, MapMinimumAlignment) {
TEST_P(SharedMemoryTest, MapMinimumAlignment) {
static const int kDataSize = 8192;

SharedMemory shared_memory;
Expand All @@ -656,7 +682,7 @@ TEST(SharedMemoryTest, MapMinimumAlignment) {
}

#if defined(OS_WIN)
TEST(SharedMemoryTest, UnsafeImageSection) {
TEST_P(SharedMemoryTest, UnsafeImageSection) {
const char kTestSectionName[] = "UnsafeImageSection";
wchar_t path[MAX_PATH];
EXPECT_GT(::GetModuleFileName(nullptr, path, arraysize(path)), 0U);
Expand Down Expand Up @@ -784,7 +810,7 @@ MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) {
#endif // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) &&
// !defined(OS_FUCHSIA)

TEST(SharedMemoryTest, MappedId) {
TEST_P(SharedMemoryTest, MappedId) {
const uint32_t kDataSize = 1024;
SharedMemory memory;
SharedMemoryCreateOptions options;
Expand All @@ -809,4 +835,13 @@ TEST(SharedMemoryTest, MappedId) {
EXPECT_TRUE(memory.mapped_id().is_empty());
}

INSTANTIATE_TEST_CASE_P(Default,
SharedMemoryTest,
::testing::Values(Mode::Default));
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
INSTANTIATE_TEST_CASE_P(SkipDevShm,
SharedMemoryTest,
::testing::Values(Mode::DisableDevShm));
#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)

} // namespace base

0 comments on commit 1824e57

Please sign in to comment.