win: Make ProcessSnapshotTest.CrashpadInfoChild use a loaded module

When this test examines a module that doesn’t have a CodeView PDB link,
it will fail. Such a link may be missing when linking with Lexan
ld-link.exe without /DEBUG. The test had been examining the executable
as its module. Since it’s easier to provide a single small module linked
with /DEBUG than it is to require that the test executable always be
linked with /DEBUG, the test is revised to always load a module and
operate on it. The module used is the existing
crashpad_snapshot_test_image_reader_module.dll. It was chosen because
it’s also used by PEImageReader.DebugDirectory, which also requires a
CodeView PDB link.

It’s the build system’s responsibility to ensure that
crashpad_snapshot_test_image_reader_module.dll is linked appropriately.
Crashpad’s own GYP-based build always links with /DEBUG. Chrome’s
GN-based Crashpad build will require additional attention at
symbol_level = 0.

Bug: chromium:782781
Change-Id: I0dda8cd13278b82842263e76bcc46362bd3998df
Reviewed-on: https://chromium-review.googlesource.com/761501
Reviewed-by: Leonard Mosescu <mosescu@chromium.org>
This commit is contained in:
Mark Mentovai 2017-11-09 15:27:25 -05:00
parent e2b9ab3ed2
commit 0e3c38a4ca
2 changed files with 28 additions and 15 deletions

View File

@ -23,42 +23,52 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "snapshot/win/process_reader_win.h" #include "snapshot/win/process_reader_win.h"
#include "test/errors.h" #include "test/errors.h"
#include "test/scoped_module_handle.h"
#include "test/test_paths.h" #include "test/test_paths.h"
#include "util/misc/from_pointer_cast.h" #include "util/misc/from_pointer_cast.h"
#include "util/win/get_module_information.h" #include "util/win/get_module_information.h"
#include "util/win/module_version.h" #include "util/win/module_version.h"
#include "util/win/process_info.h" #include "util/win/process_info.h"
extern "C" IMAGE_DOS_HEADER __ImageBase;
namespace crashpad { namespace crashpad {
namespace test { namespace test {
namespace { namespace {
TEST(PEImageReader, DebugDirectory) { TEST(PEImageReader, DebugDirectory) {
base::FilePath module_path =
TestPaths::BuildArtifact(L"snapshot",
L"image_reader_module",
TestPaths::FileType::kLoadableModule);
ScopedModuleHandle module_handle(LoadLibrary(module_path.value().c_str()));
ASSERT_TRUE(module_handle.valid()) << ErrorMessage("LoadLibrary");
PEImageReader pe_image_reader; PEImageReader pe_image_reader;
ProcessReaderWin process_reader; ProcessReaderWin process_reader;
ASSERT_TRUE(process_reader.Initialize(GetCurrentProcess(), ASSERT_TRUE(process_reader.Initialize(GetCurrentProcess(),
ProcessSuspensionState::kRunning)); ProcessSuspensionState::kRunning));
HMODULE self = reinterpret_cast<HMODULE>(&__ImageBase);
MODULEINFO module_info; MODULEINFO module_info;
ASSERT_TRUE(CrashpadGetModuleInformation( ASSERT_TRUE(CrashpadGetModuleInformation(GetCurrentProcess(),
GetCurrentProcess(), self, &module_info, sizeof(module_info))) module_handle.get(),
&module_info,
sizeof(module_info)))
<< ErrorMessage("GetModuleInformation"); << ErrorMessage("GetModuleInformation");
EXPECT_EQ(module_info.lpBaseOfDll, self); EXPECT_EQ(module_info.lpBaseOfDll, module_handle.get());
ASSERT_TRUE(pe_image_reader.Initialize(&process_reader,
FromPointerCast<WinVMAddress>(self), base::FilePath module_basename = module_path.BaseName();
module_info.SizeOfImage, ASSERT_TRUE(pe_image_reader.Initialize(
"self")); &process_reader,
FromPointerCast<WinVMAddress>(module_handle.get()),
module_info.SizeOfImage,
base::UTF16ToUTF8(module_basename.value())));
UUID uuid; UUID uuid;
DWORD age; DWORD age;
std::string pdbname; std::string pdbname;
ASSERT_TRUE(pe_image_reader.DebugDirectoryInformation(&uuid, &age, &pdbname)); ASSERT_TRUE(pe_image_reader.DebugDirectoryInformation(&uuid, &age, &pdbname));
std::string self_name = base::UTF16ToUTF8( std::string module_name =
TestPaths::ExpectedExecutableBasename(L"crashpad_snapshot_test") base::UTF16ToUTF8(module_basename.RemoveFinalExtension().value());
.RemoveFinalExtension() EXPECT_NE(pdbname.find(module_name), std::string::npos);
.value());
EXPECT_NE(pdbname.find(self_name), std::string::npos);
const std::string suffix(".pdb"); const std::string suffix(".pdb");
EXPECT_EQ( EXPECT_EQ(
pdbname.compare(pdbname.size() - suffix.size(), suffix.size(), suffix), pdbname.compare(pdbname.size() - suffix.size(), suffix.size(), suffix),

View File

@ -59,6 +59,9 @@ class ScopedModuleHandle {
explicit ScopedModuleHandle(ModuleHandle handle); explicit ScopedModuleHandle(ModuleHandle handle);
~ScopedModuleHandle(); ~ScopedModuleHandle();
//! \return The module handle being managed.
ModuleHandle get() const { return handle_; }
//! \return `true` if this object manages a valid loadable module handle. //! \return `true` if this object manages a valid loadable module handle.
bool valid() const { return handle_ != nullptr; } bool valid() const { return handle_ != nullptr; }