diff --git a/.github/workflows/bazel_test_centipede.yml b/.github/workflows/bazel_test_centipede.yml index 9d4355c3..87640271 100644 --- a/.github/workflows/bazel_test_centipede.yml +++ b/.github/workflows/bazel_test_centipede.yml @@ -108,19 +108,25 @@ jobs: if: ${{ !cancelled() }} run: | bazel test --local_test_jobs=1 --test_output=errors --no//fuzztest:use_riegeli \ - centipede:binary_info_test centipede:call_graph_test \ - centipede:callstack_test centipede:concurrent_bitset_test \ + centipede:binary_info_test centipede:byte_array_mutator_test \ + centipede:call_graph_test centipede:callstack_test \ + centipede:centipede_binary_test centipede:concurrent_bitset_test \ centipede:command_test \ centipede:concurrent_byteset_test centipede:config_file_test \ - centipede:config_util_test centipede:environment_test \ + centipede:config_util_test centipede:corpus_io_test \ + centipede:corpus_test centipede:distill_test \ + centipede:environment_test centipede:execution_metadata_test \ centipede:feature_set_test centipede:feature_test \ centipede:foreach_nonzero_test \ centipede:hashed_ring_buffer_test centipede:int_utils_test \ - centipede:knobs_test centipede:pc_info_test \ - centipede:resource_pool_test \ + centipede:knobs_test centipede:mutation_input_test \ + centipede:pc_info_test centipede:resource_pool_test \ centipede:reverse_pc_table_test centipede:rolling_hash_test \ centipede:runner_cmp_trace_test centipede:runner_flags_test \ - centipede:rusage_stats_test \ + centipede:runner_result_test centipede:rusage_stats_test \ + centipede:seed_corpus_maker_lib_test \ + centipede:seed_corpus_maker_proto_lib_test \ + centipede:shared_memory_blob_sequence_test \ centipede:stats_test centipede:symbol_table_test \ centipede:util_test centipede:workdir_test && \ bazel test --local_test_jobs=1 --test_output=errors --no//fuzztest:use_riegeli --test_filter='-*ValidateTimelapseSnapshots' -- centipede:rusage_profiler_test diff --git a/centipede/BUILD b/centipede/BUILD index be39ea23..7669751b 100644 --- a/centipede/BUILD +++ b/centipede/BUILD @@ -425,7 +425,12 @@ cc_library( name = "shared_memory_blob_sequence", srcs = ["shared_memory_blob_sequence.cc"], hdrs = ["shared_memory_blob_sequence.h"], - linkopts = ["-lrt"], # for shm_open. + linkopts = select({ + "@platforms//os:macos": [], + "//conditions:default": [ + "-lrt", # for shm_open + ], + }), visibility = PUBLIC_API_VISIBILITY, deps = ["@com_google_absl//absl/base:nullability"], # don't add any dependencies. diff --git a/centipede/environment.h b/centipede/environment.h index 47f4db66..a2b25002 100644 --- a/centipede/environment.h +++ b/centipede/environment.h @@ -98,7 +98,11 @@ struct Environment { std::string minimize_crash_file_path; bool batch_triage_suspect_only = false; size_t shmem_size_mb = 1024; +#ifdef __APPLE__ + bool use_posix_shmem = true; +#else bool use_posix_shmem = false; +#endif bool dry_run = false; bool save_binary_info = false; bool populate_binary_info = true; diff --git a/centipede/execution_metadata_test.cc b/centipede/execution_metadata_test.cc index ccfb565c..c7d7edd4 100644 --- a/centipede/execution_metadata_test.cc +++ b/centipede/execution_metadata_test.cc @@ -14,6 +14,7 @@ #include "./centipede/execution_metadata.h" +#include #include #include @@ -96,8 +97,9 @@ TEST(ExecutionMetadata, AppendCmpEntryReturnsFalseAndSkipsOnBadArgs) { TEST(ExecutionMetadata, ReadAndWriteKeepsCmpEntries) { ExecutionMetadata metadata_in; ASSERT_TRUE(metadata_in.AppendCmpEntry({1, 2}, {3, 4})); - SharedMemoryBlobSequence blobseq("test", /*size=*/1024, - /*use_posix_shmem=*/false); + std::vector blob_storage; + blob_storage.resize(1024); + BlobSequence blobseq(blob_storage.data(), blob_storage.size()); EXPECT_TRUE(metadata_in.Write(/*tag=*/1, blobseq)); blobseq.Reset(); Blob blob = blobseq.Read(); diff --git a/centipede/shared_memory_blob_sequence.cc b/centipede/shared_memory_blob_sequence.cc index 5ad51b8f..a60ad856 100644 --- a/centipede/shared_memory_blob_sequence.cc +++ b/centipede/shared_memory_blob_sequence.cc @@ -108,6 +108,9 @@ SharedMemoryBlobSequence::SharedMemoryBlobSequence(const char *name, "shm_open() path length exceeds PATH_MAX."); path_is_owned_ = true; } else { +#ifdef __APPLE__ + ErrorOnFailure(true, "must use POSIX shmem"); +#else // __APPLE__ fd_ = memfd_create(name, MFD_CLOEXEC); ErrorOnFailure(fd_ < 0, "memfd_create() failed"); const size_t path_size = @@ -116,8 +119,9 @@ SharedMemoryBlobSequence::SharedMemoryBlobSequence(const char *name, "internal fd path length exceeds PATH_MAX."); // memfd_create descriptors are automatically freed on close(). path_is_owned_ = false; +#endif // __APPLE__ } - ErrorOnFailure(ftruncate(fd_, static_cast<__off_t>(size_)), + ErrorOnFailure(ftruncate(fd_, static_cast(size_)), "ftruncate() failed)"); MmapData(); } @@ -154,10 +158,16 @@ SharedMemoryBlobSequence::~SharedMemoryBlobSequence() { } void SharedMemoryBlobSequence::ReleaseSharedMemory() { +#ifdef __APPLE__ + // MacOS only allows ftruncate shm once + // (https://stackoverflow.com/questions/25502229/ftruncate-not-working-on-posix-shared-memory-in-mac-os-x). + // So nothing we can do here. +#else // __APPLE__ // Setting size to 0 releases the memory to OS. ErrorOnFailure(ftruncate(fd_, 0) != 0, "ftruncate(0) failed)"); // Set the size back to `size`. The memory is not actually reserved. ErrorOnFailure(ftruncate(fd_, size_) != 0, "ftruncate(size_) failed)"); +#endif // __APPLE__ } size_t SharedMemoryBlobSequence::NumBytesUsed() const { diff --git a/centipede/shared_memory_blob_sequence_test.cc b/centipede/shared_memory_blob_sequence_test.cc index c549b995..83b9df16 100644 --- a/centipede/shared_memory_blob_sequence_test.cc +++ b/centipede/shared_memory_blob_sequence_test.cc @@ -28,8 +28,7 @@ namespace centipede { std::string ShmemName() { std::ostringstream oss; - oss << "/shared_memory_blob_sequence_test-" << getpid() << "-" - << std::this_thread::get_id(); + oss << "/shm_test-" << getpid() << "-" << std::this_thread::get_id(); return oss.str(); } @@ -54,7 +53,17 @@ TEST(BlobSequence, WriteAndReadAnEmptyBlob) { } class SharedMemoryBlobSequenceTest - : public testing::TestWithParam {}; + : public testing::TestWithParam { + public: + void SetUp() override { +#ifdef __APPLE__ + const bool use_shm = GetParam(); + if (!use_shm) { + GTEST_SKIP() << "Skipping test that does not use POSIX shmem on MacOS"; + } +#endif // __APPLE__ + } +}; INSTANTIATE_TEST_SUITE_P(SharedMemoryBlobSequenceParametrizedTest, SharedMemoryBlobSequenceTest, @@ -195,6 +204,8 @@ TEST_P(SharedMemoryBlobSequenceTest, WriteAfterReset) { EXPECT_FALSE(blob2.IsValid()); } +// MacOS does not support releasing the shm memory. +#ifndef __APPLE__ // Test ReleaseSharedMemory and NumBytesUsed. TEST_P(SharedMemoryBlobSequenceTest, ReleaseSharedMemory) { // Allocate a blob sequence with 1M bytes of storage. @@ -207,5 +218,6 @@ TEST_P(SharedMemoryBlobSequenceTest, ReleaseSharedMemory) { EXPECT_TRUE(blobseq.Write(Blob({1, 2, 3, 4}))); EXPECT_GT(blobseq.NumBytesUsed(), 5); } +#endif } // namespace centipede