mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Rework ElfImageReader.MainExecutableChild to not rely on fork()
Switches from test::Multiprocess to test::MultiprocessExec for ElfImageReader.MainExecutableChild. Uses the new child process launching, and passes the expected symbol address from the child to the parent, rather than assuming the value will be the same in both processes. And, enables the test on Fuchsia since it now works. Bug: crashpad:196, crashpad:215 Change-Id: I3b43407b6584275d61bedc9c13d1625b950fc23b Reviewed-on: https://chromium-review.googlesource.com/884993 Commit-Queue: Scott Graham <scottmg@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
48abd4a60f
commit
11589d9b32
@ -21,6 +21,7 @@
|
||||
#include "build/build_config.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/multiprocess.h"
|
||||
#include "test/multiprocess_exec.h"
|
||||
#include "test/process_type.h"
|
||||
#include "util/file/file_io.h"
|
||||
#include "util/misc/address_types.h"
|
||||
@ -68,6 +69,8 @@ void LocateExecutable(ProcessType process,
|
||||
sizeof(debug_address));
|
||||
ASSERT_EQ(status, ZX_OK)
|
||||
<< "zx_object_get_property: ZX_PROP_PROCESS_DEBUG_ADDR";
|
||||
// Can be 0 if requested before the loader has loaded anything.
|
||||
EXPECT_NE(debug_address, 0u);
|
||||
|
||||
constexpr auto k_r_debug_map_offset = offsetof(r_debug, r_map);
|
||||
uintptr_t map;
|
||||
@ -120,7 +123,8 @@ void ExpectSymbol(ElfImageReader* reader,
|
||||
reader->GetDynamicSymbol("notasymbol", &symbol_address, &symbol_size));
|
||||
}
|
||||
|
||||
void ReadThisExecutableInTarget(ProcessType process) {
|
||||
void ReadThisExecutableInTarget(ProcessType process,
|
||||
VMAddress exported_symbol_address) {
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
constexpr bool am_64_bit = true;
|
||||
#else
|
||||
@ -139,9 +143,8 @@ void ReadThisExecutableInTarget(ProcessType process) {
|
||||
ElfImageReader reader;
|
||||
ASSERT_TRUE(reader.Initialize(range, elf_address));
|
||||
|
||||
ExpectSymbol(&reader,
|
||||
"ElfImageReaderTestExportedSymbol",
|
||||
FromPointerCast<VMAddress>(ElfImageReaderTestExportedSymbol));
|
||||
ExpectSymbol(
|
||||
&reader, "ElfImageReaderTestExportedSymbol", exported_symbol_address);
|
||||
|
||||
ElfImageReader::NoteReader::Result result;
|
||||
std::string note_name;
|
||||
@ -201,25 +204,45 @@ void ReadLibcInTarget(ProcessType process) {
|
||||
}
|
||||
|
||||
TEST(ElfImageReader, MainExecutableSelf) {
|
||||
ReadThisExecutableInTarget(GetSelfProcess());
|
||||
ReadThisExecutableInTarget(
|
||||
GetSelfProcess(),
|
||||
FromPointerCast<VMAddress>(ElfImageReaderTestExportedSymbol));
|
||||
}
|
||||
|
||||
#if !defined(OS_FUCHSIA) // TODO(scottmg): Port to MultiprocessExec.
|
||||
class ReadExecutableChildTest : public Multiprocess {
|
||||
CRASHPAD_CHILD_TEST_MAIN(ReadExecutableChild) {
|
||||
VMAddress exported_symbol_address =
|
||||
FromPointerCast<VMAddress>(ElfImageReaderTestExportedSymbol);
|
||||
CheckedWriteFile(StdioFileHandle(StdioStream::kStandardOutput),
|
||||
&exported_symbol_address,
|
||||
sizeof(exported_symbol_address));
|
||||
CheckedReadFileAtEOF(StdioFileHandle(StdioStream::kStandardInput));
|
||||
return 0;
|
||||
}
|
||||
|
||||
class ReadExecutableChildTest : public MultiprocessExec {
|
||||
public:
|
||||
ReadExecutableChildTest() : Multiprocess() {}
|
||||
~ReadExecutableChildTest() {}
|
||||
ReadExecutableChildTest() : MultiprocessExec() {}
|
||||
|
||||
private:
|
||||
void MultiprocessParent() { ReadThisExecutableInTarget(ChildPID()); }
|
||||
void MultiprocessChild() { CheckedReadFileAtEOF(ReadPipeHandle()); }
|
||||
void MultiprocessParent() {
|
||||
// This read serves two purposes -- on Fuchsia, the loader may have not
|
||||
// filled in debug address as soon as the child process handle is valid, so
|
||||
// this causes a wait at least until the main() of the child, at which point
|
||||
// it will always be valid. Secondarily, the address of the symbol to be
|
||||
// looked up needs to be communicated.
|
||||
VMAddress exported_symbol_address;
|
||||
CheckedReadFileExactly(ReadPipeHandle(),
|
||||
&exported_symbol_address,
|
||||
sizeof(exported_symbol_address));
|
||||
ReadThisExecutableInTarget(ChildProcess(), exported_symbol_address);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(ElfImageReader, MainExecutableChild) {
|
||||
ReadExecutableChildTest test;
|
||||
test.SetChildTestMainFunction("ReadExecutableChild");
|
||||
test.Run();
|
||||
}
|
||||
#endif // !OS_FUCHSIA
|
||||
|
||||
TEST(ElfImageReader, OneModuleSelf) {
|
||||
ReadLibcInTarget(GetSelfProcess());
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "base/macros.h"
|
||||
#include "build/build_config.h"
|
||||
#include "test/multiprocess.h"
|
||||
#include "test/process_type.h"
|
||||
|
||||
//! \file
|
||||
|
||||
@ -117,6 +118,13 @@ class MultiprocessExec : public Multiprocess {
|
||||
//! CRASHPAD_CHILD_TEST_MAIN().
|
||||
void SetChildTestMainFunction(const std::string& function_name);
|
||||
|
||||
//! \brief Returns a ProcessType representing the child process.
|
||||
//!
|
||||
//! This method is only valid during the body of MultiprocessParent().
|
||||
//!
|
||||
//! \return A platform-specific type representing the child process.
|
||||
ProcessType ChildProcess();
|
||||
|
||||
protected:
|
||||
~MultiprocessExec();
|
||||
|
||||
|
@ -177,5 +177,9 @@ void MultiprocessExec::MultiprocessChild() {
|
||||
info()->child.reset(child);
|
||||
}
|
||||
|
||||
ProcessType MultiprocessExec::ChildProcess() {
|
||||
return info()->child.get();
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
@ -148,5 +148,9 @@ void MultiprocessExec::MultiprocessChild() {
|
||||
FAIL() << ErrnoMessage("execv") << ": " << argv_[0];
|
||||
}
|
||||
|
||||
ProcessType MultiprocessExec::ChildProcess() {
|
||||
return ChildPID();
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
@ -170,5 +170,9 @@ void MultiprocessExec::MultiprocessChild() {
|
||||
&info()->process_info));
|
||||
}
|
||||
|
||||
ProcessType MultiprocessExec::ChildProcess() {
|
||||
return info()->process_info.hProcess;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
Loading…
x
Reference in New Issue
Block a user