#include "util/process/process_memory.h"
#include <string.h>
#include "base/containers/heap_array.h"
#include "base/memory/page_size.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/multiprocess.h"
#include "test/multiprocess_exec.h"
#include "test/process_type.h"
#include "test/scoped_guarded_page.h"
#include "util/file/file_io.h"
#include "util/misc/from_pointer_cast.h"
#include "util/process/process_memory_native.h"
#if BUILDFLAG(IS_APPLE)
#include "test/mac/mach_multiprocess.h"
#endif
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "test/linux/fake_ptrace_connection.h"
#include "util/linux/direct_ptrace_connection.h"
#endif
namespace crashpad {
namespace test {
namespace {
#if BUILDFLAG(IS_APPLE)
class MultiprocessAdaptor : public MachMultiprocess {
public:
void SetChildTestMainFunction(const std::string& function_name) {
test_function_ = function_name;
}
ProcessType ChildProcess() { return ChildTask(); }
static FileHandle OutputHandle() {
CHECK_NE(write_pipe_handle_, -1);
return write_pipe_handle_;
}
static FileHandle InputHandle() {
CHECK_NE(read_pipe_handle_, -1);
return read_pipe_handle_;
}
private:
virtual void Parent() = 0;
void MachMultiprocessParent() override { Parent(); }
void MachMultiprocessChild() override {
read_pipe_handle_ = ReadPipeHandle();
write_pipe_handle_ = WritePipeHandle();
internal::CheckedInvokeMultiprocessChild(test_function_);
}
std::string test_function_;
static FileHandle read_pipe_handle_;
static FileHandle write_pipe_handle_;
};
FileHandle MultiprocessAdaptor::read_pipe_handle_ = -1;
FileHandle MultiprocessAdaptor::write_pipe_handle_ = -1;
#else
class MultiprocessAdaptor : public MultiprocessExec { … };
#endif
base::HeapArray<char> DoChildReadTestSetup() { … }
CRASHPAD_CHILD_TEST_MAIN(ReadTestChild) { … }
class ReadTest : public MultiprocessAdaptor { … };
TEST(ProcessMemory, ReadSelf) { … }
TEST(ProcessMemory, ReadChild) { … }
constexpr char kConstCharEmpty[] = …;
constexpr char kConstCharShort[] = …;
#define SHORT_LOCAL_STRING …
std::string MakeLongString() { … }
void DoChildCStringReadTestSetup(const char** const_empty,
const char** const_short,
const char** local_empty,
const char** local_short,
std::string* long_string) { … }
CRASHPAD_CHILD_TEST_MAIN(ReadCStringTestChild) { … }
class ReadCStringTest : public MultiprocessAdaptor { … };
TEST(ProcessMemory, ReadCStringSelf) { … }
TEST(ProcessMemory, ReadCStringChild) { … }
TEST(ProcessMemory, ReadCStringSizeLimitedSelf) { … }
TEST(ProcessMemory, ReadCStringSizeLimitedChild) { … }
void DoReadUnmappedChildMainSetup(void* page) { … }
CRASHPAD_CHILD_TEST_MAIN(ReadUnmappedChildMain) { … }
class ReadUnmappedTest : public MultiprocessAdaptor { … };
TEST(ProcessMemory, ReadUnmappedChild) { … }
constexpr size_t kChildProcessStringLength = …;
class StringDataInChildProcess { … };
void DoCStringUnmappedTestSetup(
void* page,
std::vector<StringDataInChildProcess>* strings) { … }
CRASHPAD_CHILD_TEST_MAIN(ReadCStringUnmappedChildMain) { … }
class ReadCStringUnmappedTest : public MultiprocessAdaptor { … };
TEST(ProcessMemory, ReadCStringUnmappedChild) { … }
TEST(ProcessMemory, ReadCStringSizeLimitedUnmappedChild) { … }
}
}
}