Commit 1824e575 authored by David Vallet's avatar David Vallet Committed by Commit Bot

Add switch to always use temp dir in shared memory instances on Linux 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/810325Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Commit-Queue: David Vallet <dvallet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523959}
parent 1050c3ac
...@@ -112,6 +112,14 @@ const char kProfilingFile[] = "profiling-file"; ...@@ -112,6 +112,14 @@ const char kProfilingFile[] = "profiling-file";
const char kDisableUsbKeyboardDetect[] = "disable-usb-keyboard-detect"; const char kDisableUsbKeyboardDetect[] = "disable-usb-keyboard-detect";
#endif #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) #if defined(OS_POSIX)
// Used for turning on Breakpad crash reporting in a debug environment where // Used for turning on Breakpad crash reporting in a debug environment where
// crash reporting is typically compiled but disabled. // crash reporting is typically compiled but disabled.
......
...@@ -37,6 +37,10 @@ extern const char kWaitForDebugger[]; ...@@ -37,6 +37,10 @@ extern const char kWaitForDebugger[];
extern const char kDisableUsbKeyboardDetect[]; extern const char kDisableUsbKeyboardDetect[];
#endif #endif
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
extern const char kDisableDevShmUsage[];
#endif
#if defined(OS_POSIX) #if defined(OS_POSIX)
extern const char kEnableCrashReporterForTesting[]; extern const char kEnableCrashReporterForTesting[];
#endif #endif
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/stack.h" #include "base/containers/stack.h"
#include "base/environment.h" #include "base/environment.h"
#include "base/files/file_enumerator.h" #include "base/files/file_enumerator.h"
...@@ -985,16 +987,21 @@ int GetMaximumPathComponentLength(const FilePath& path) { ...@@ -985,16 +987,21 @@ int GetMaximumPathComponentLength(const FilePath& path) {
// This is implemented in file_util_android.cc for that platform. // This is implemented in file_util_android.cc for that platform.
bool GetShmemTempDir(bool executable, FilePath* path) { bool GetShmemTempDir(bool executable, FilePath* path) {
#if defined(OS_LINUX) || defined(OS_AIX) #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; bool use_dev_shm = true;
if (executable) { if (executable) {
static const bool s_dev_shm_executable = DetermineDevShmExecutable(); static const bool s_dev_shm_executable = DetermineDevShmExecutable();
use_dev_shm = s_dev_shm_executable; use_dev_shm = s_dev_shm_executable;
} }
if (use_dev_shm) { if (use_dev_shm && !disable_dev_shm) {
*path = FilePath("/dev/shm"); *path = FilePath("/dev/shm");
return true; return true;
} }
#endif #endif // defined(OS_LINUX) || defined(OS_AIX)
return GetTempDir(path); return GetTempDir(path);
} }
#endif // !defined(OS_ANDROID) #endif // !defined(OS_ANDROID)
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <memory> #include <memory>
#include "base/atomicops.h" #include "base/atomicops.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/shared_memory_handle.h" #include "base/memory/shared_memory_handle.h"
#include "base/process/kill.h" #include "base/process/kill.h"
...@@ -100,12 +102,36 @@ const char MultipleThreadMain::s_test_name_[] = ...@@ -100,12 +102,36 @@ const char MultipleThreadMain::s_test_name_[] =
"SharedMemoryOpenThreadTest"; "SharedMemoryOpenThreadTest";
#endif // !defined(OS_MACOSX) && !defined(OS_FUCHSIA) #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 } // namespace
// Android/Mac/Fuchsia doesn't support SharedMemory::Open/Delete/ // Android/Mac/Fuchsia doesn't support SharedMemory::Open/Delete/
// CreateNamedDeprecated(openExisting=true) // CreateNamedDeprecated(openExisting=true)
#if !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA) #if !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
TEST(SharedMemoryTest, OpenClose) {
TEST_P(SharedMemoryTest, OpenClose) {
const uint32_t kDataSize = 1024; const uint32_t kDataSize = 1024;
std::string test_name = "SharedMemoryOpenCloseTest"; std::string test_name = "SharedMemoryOpenCloseTest";
...@@ -153,7 +179,7 @@ TEST(SharedMemoryTest, OpenClose) { ...@@ -153,7 +179,7 @@ TEST(SharedMemoryTest, OpenClose) {
EXPECT_TRUE(rv); EXPECT_TRUE(rv);
} }
TEST(SharedMemoryTest, OpenExclusive) { TEST_P(SharedMemoryTest, OpenExclusive) {
const uint32_t kDataSize = 1024; const uint32_t kDataSize = 1024;
const uint32_t kDataSize2 = 2048; const uint32_t kDataSize2 = 2048;
std::ostringstream test_name_stream; std::ostringstream test_name_stream;
...@@ -221,7 +247,7 @@ TEST(SharedMemoryTest, OpenExclusive) { ...@@ -221,7 +247,7 @@ TEST(SharedMemoryTest, OpenExclusive) {
#endif // !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA) #endif // !defined(OS_ANDROID) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
// Check that memory is still mapped after its closed. // Check that memory is still mapped after its closed.
TEST(SharedMemoryTest, CloseNoUnmap) { TEST_P(SharedMemoryTest, CloseNoUnmap) {
const size_t kDataSize = 4096; const size_t kDataSize = 4096;
SharedMemory memory; SharedMemory memory;
...@@ -246,7 +272,7 @@ TEST(SharedMemoryTest, CloseNoUnmap) { ...@@ -246,7 +272,7 @@ TEST(SharedMemoryTest, CloseNoUnmap) {
#if !defined(OS_MACOSX) && !defined(OS_FUCHSIA) #if !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
// Create a set of N threads to each open a shared memory segment and write to // 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. // it. Verify that they are always reading/writing consistent data.
TEST(SharedMemoryTest, MultipleThreads) { TEST_P(SharedMemoryTest, MultipleThreads) {
const int kNumThreads = 5; const int kNumThreads = 5;
MultipleThreadMain::CleanUp(); MultipleThreadMain::CleanUp();
...@@ -287,7 +313,7 @@ TEST(SharedMemoryTest, MultipleThreads) { ...@@ -287,7 +313,7 @@ TEST(SharedMemoryTest, MultipleThreads) {
// Allocate private (unique) shared memory with an empty string for a // 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 // name. Make sure several of them don't point to the same thing as
// we might expect if the names are equal. // we might expect if the names are equal.
TEST(SharedMemoryTest, AnonymousPrivate) { TEST_P(SharedMemoryTest, AnonymousPrivate) {
int i, j; int i, j;
int count = 4; int count = 4;
bool rv; bool rv;
...@@ -328,7 +354,7 @@ TEST(SharedMemoryTest, AnonymousPrivate) { ...@@ -328,7 +354,7 @@ TEST(SharedMemoryTest, AnonymousPrivate) {
} }
} }
TEST(SharedMemoryTest, GetReadOnlyHandle) { TEST_P(SharedMemoryTest, GetReadOnlyHandle) {
StringPiece contents = "Hello World"; StringPiece contents = "Hello World";
SharedMemory writable_shmem; SharedMemory writable_shmem;
...@@ -430,7 +456,7 @@ TEST(SharedMemoryTest, GetReadOnlyHandle) { ...@@ -430,7 +456,7 @@ TEST(SharedMemoryTest, GetReadOnlyHandle) {
#endif // defined(OS_POSIX) || defined(OS_WIN) #endif // defined(OS_POSIX) || defined(OS_WIN)
} }
TEST(SharedMemoryTest, ShareToSelf) { TEST_P(SharedMemoryTest, ShareToSelf) {
StringPiece contents = "Hello World"; StringPiece contents = "Hello World";
SharedMemory shmem; SharedMemory shmem;
...@@ -461,7 +487,7 @@ TEST(SharedMemoryTest, ShareToSelf) { ...@@ -461,7 +487,7 @@ TEST(SharedMemoryTest, ShareToSelf) {
contents.size())); contents.size()));
} }
TEST(SharedMemoryTest, ShareWithMultipleInstances) { TEST_P(SharedMemoryTest, ShareWithMultipleInstances) {
static const StringPiece kContents = "Hello World"; static const StringPiece kContents = "Hello World";
SharedMemory shmem; SharedMemory shmem;
...@@ -505,7 +531,7 @@ TEST(SharedMemoryTest, ShareWithMultipleInstances) { ...@@ -505,7 +531,7 @@ TEST(SharedMemoryTest, ShareWithMultipleInstances) {
ASSERT_EQ(StringPiece(ToLowerASCII(kContents)), readonly_contents); ASSERT_EQ(StringPiece(ToLowerASCII(kContents)), readonly_contents);
} }
TEST(SharedMemoryTest, MapAt) { TEST_P(SharedMemoryTest, MapAt) {
ASSERT_TRUE(SysInfo::VMAllocationGranularity() >= sizeof(uint32_t)); ASSERT_TRUE(SysInfo::VMAllocationGranularity() >= sizeof(uint32_t));
const size_t kCount = SysInfo::VMAllocationGranularity(); const size_t kCount = SysInfo::VMAllocationGranularity();
const size_t kDataSize = kCount * sizeof(uint32_t); const size_t kDataSize = kCount * sizeof(uint32_t);
...@@ -531,7 +557,7 @@ TEST(SharedMemoryTest, MapAt) { ...@@ -531,7 +557,7 @@ TEST(SharedMemoryTest, MapAt) {
} }
} }
TEST(SharedMemoryTest, MapTwice) { TEST_P(SharedMemoryTest, MapTwice) {
const uint32_t kDataSize = 1024; const uint32_t kDataSize = 1024;
SharedMemory memory; SharedMemory memory;
bool rv = memory.CreateAndMapAnonymous(kDataSize); bool rv = memory.CreateAndMapAnonymous(kDataSize);
...@@ -548,7 +574,7 @@ TEST(SharedMemoryTest, MapTwice) { ...@@ -548,7 +574,7 @@ TEST(SharedMemoryTest, MapTwice) {
// This test is not applicable for iOS (crbug.com/399384). // This test is not applicable for iOS (crbug.com/399384).
#if !defined(OS_IOS) #if !defined(OS_IOS)
// Create a shared memory object, mmap it, and mprotect it to PROT_EXEC. // 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; const uint32_t kTestSize = 1 << 16;
SharedMemory shared_memory; SharedMemory shared_memory;
...@@ -588,7 +614,7 @@ class ScopedUmaskSetter { ...@@ -588,7 +614,7 @@ class ScopedUmaskSetter {
}; };
// Create a shared memory object, check its permissions. // Create a shared memory object, check its permissions.
TEST(SharedMemoryTest, FilePermissionsAnonymous) { TEST_P(SharedMemoryTest, FilePermissionsAnonymous) {
const uint32_t kTestSize = 1 << 8; const uint32_t kTestSize = 1 << 8;
SharedMemory shared_memory; SharedMemory shared_memory;
...@@ -614,7 +640,7 @@ TEST(SharedMemoryTest, FilePermissionsAnonymous) { ...@@ -614,7 +640,7 @@ TEST(SharedMemoryTest, FilePermissionsAnonymous) {
} }
// Create a shared memory object, check its permissions. // Create a shared memory object, check its permissions.
TEST(SharedMemoryTest, FilePermissionsNamed) { TEST_P(SharedMemoryTest, FilePermissionsNamed) {
const uint32_t kTestSize = 1 << 8; const uint32_t kTestSize = 1 << 8;
SharedMemory shared_memory; SharedMemory shared_memory;
...@@ -645,7 +671,7 @@ TEST(SharedMemoryTest, FilePermissionsNamed) { ...@@ -645,7 +671,7 @@ TEST(SharedMemoryTest, FilePermissionsNamed) {
// Map() will return addresses which are aligned to the platform page size, this // 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 // varies from platform to platform though. Since we'd like to advertise a
// minimum alignment that callers can count on, test for it here. // minimum alignment that callers can count on, test for it here.
TEST(SharedMemoryTest, MapMinimumAlignment) { TEST_P(SharedMemoryTest, MapMinimumAlignment) {
static const int kDataSize = 8192; static const int kDataSize = 8192;
SharedMemory shared_memory; SharedMemory shared_memory;
...@@ -656,7 +682,7 @@ TEST(SharedMemoryTest, MapMinimumAlignment) { ...@@ -656,7 +682,7 @@ TEST(SharedMemoryTest, MapMinimumAlignment) {
} }
#if defined(OS_WIN) #if defined(OS_WIN)
TEST(SharedMemoryTest, UnsafeImageSection) { TEST_P(SharedMemoryTest, UnsafeImageSection) {
const char kTestSectionName[] = "UnsafeImageSection"; const char kTestSectionName[] = "UnsafeImageSection";
wchar_t path[MAX_PATH]; wchar_t path[MAX_PATH];
EXPECT_GT(::GetModuleFileName(nullptr, path, arraysize(path)), 0U); EXPECT_GT(::GetModuleFileName(nullptr, path, arraysize(path)), 0U);
...@@ -784,7 +810,7 @@ MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) { ...@@ -784,7 +810,7 @@ MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) {
#endif // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) && #endif // !defined(OS_IOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) &&
// !defined(OS_FUCHSIA) // !defined(OS_FUCHSIA)
TEST(SharedMemoryTest, MappedId) { TEST_P(SharedMemoryTest, MappedId) {
const uint32_t kDataSize = 1024; const uint32_t kDataSize = 1024;
SharedMemory memory; SharedMemory memory;
SharedMemoryCreateOptions options; SharedMemoryCreateOptions options;
...@@ -809,4 +835,13 @@ TEST(SharedMemoryTest, MappedId) { ...@@ -809,4 +835,13 @@ TEST(SharedMemoryTest, MappedId) {
EXPECT_TRUE(memory.mapped_id().is_empty()); 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 } // namespace base
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment