win: Tests shouldn’t freak out when CodeView PDB links are absent

crashpad_snapshot_test PEImageReader.DebugDirectory was hanging when
crashpad_snapshot_test_image_reader.exe did not have a CodeView PDB
link. This occurred when linked by Lexan ld-link.exe without /DEBUG.

Bug: chromium:782781
Change-Id: I8fbc4d8decf6ac5e19f7ffeb230fd15d7c40fd51
Reviewed-on: https://chromium-review.googlesource.com/761320
Reviewed-by: Leonard Mosescu <mosescu@chromium.org>
This commit is contained in:
Mark Mentovai 2017-11-09 14:33:15 -05:00
parent 13e17bf90f
commit e2b9ab3ed2
6 changed files with 96 additions and 17 deletions

View File

@ -53,7 +53,7 @@ TEST(PEImageReader, DebugDirectory) {
UUID uuid;
DWORD age;
std::string pdbname;
EXPECT_TRUE(pe_image_reader.DebugDirectoryInformation(&uuid, &age, &pdbname));
ASSERT_TRUE(pe_image_reader.DebugDirectoryInformation(&uuid, &age, &pdbname));
std::string self_name = base::UTF16ToUTF8(
TestPaths::ExpectedExecutableBasename(L"crashpad_snapshot_test")
.RemoveFinalExtension()

View File

@ -26,6 +26,7 @@
#include "util/file/file_io.h"
#include "util/win/scoped_handle.h"
#include "util/win/scoped_process_suspend.h"
#include "util/win/scoped_set_event.h"
namespace crashpad {
namespace test {
@ -46,6 +47,8 @@ void TestImageReaderChild(const TestPaths::Architecture architecture) {
ChildLauncher child(child_test_executable, done_uuid.ToString16());
ASSERT_NO_FATAL_FAILURE(child.Start());
ScopedSetEvent set_done(done.get());
char c;
ASSERT_TRUE(
LoggingReadFileExactly(child.stdout_read_handle(), &c, sizeof(c)));
@ -105,7 +108,7 @@ void TestImageReaderChild(const TestPaths::Architecture architecture) {
}
// Tell the child it can terminate.
EXPECT_TRUE(SetEvent(done.get())) << ErrorMessage("SetEvent");
EXPECT_TRUE(set_done.Set());
EXPECT_EQ(child.WaitForExit(), 0u);
}

View File

@ -257,6 +257,8 @@
'win/scoped_local_alloc.h',
'win/scoped_process_suspend.cc',
'win/scoped_process_suspend.h',
'win/scoped_set_event.cc',
'win/scoped_set_event.h',
'win/session_end_watcher.cc',
'win/session_end_watcher.h',
'win/termination_codes.h',

View File

@ -0,0 +1,40 @@
// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/win/scoped_set_event.h"
#include "base/logging.h"
namespace crashpad {
ScopedSetEvent::ScopedSetEvent(HANDLE event) : event_(event) {
DCHECK(event_);
}
ScopedSetEvent::~ScopedSetEvent() {
if (event_) {
Set();
}
}
bool ScopedSetEvent::Set() {
bool rv = !!SetEvent(event_);
if (!rv) {
PLOG(ERROR) << "SetEvent";
}
event_ = nullptr;
return rv;
}
} // namespace crashpad

View File

@ -0,0 +1,48 @@
// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CRASHPAD_UTIL_WIN_SCOPED_SET_EVENT_H_
#define CRASHPAD_UTIL_WIN_SCOPED_SET_EVENT_H_
#include <windows.h>
#include "base/macros.h"
namespace crashpad {
//! \brief Calls `SetEvent()` on destruction at latest.
//!
//! Does not assume ownership of the event handle. Use ScopedKernelHANDLE for
//! ownership.
class ScopedSetEvent {
public:
explicit ScopedSetEvent(HANDLE event);
~ScopedSetEvent();
//! \brief Calls `SetEvent()` immediately.
//!
//! `SetEvent()` will not be called on destruction.
//!
//! \return `true` on success, `false` on failure with a message logged.
bool Set();
private:
HANDLE event_; // weak
DISALLOW_COPY_AND_ASSIGN(ScopedSetEvent);
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_WIN_SCOPED_SET_EVENT_H_

View File

@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/scoped_generic.h"
#include "util/win/scoped_set_event.h"
extern "C" {
extern IMAGE_DOS_HEADER __ImageBase;
@ -25,21 +26,6 @@ namespace crashpad {
namespace {
class ScopedSetEvent {
public:
explicit ScopedSetEvent(HANDLE event) : event_(event) {}
~ScopedSetEvent() {
if (!SetEvent(event_)) {
PLOG(ERROR) << "SetEvent";
}
}
private:
HANDLE event_;
DISALLOW_COPY_AND_ASSIGN(ScopedSetEvent);
};
// ScopedWindowClass and ScopedWindow operate on ATOM* and HWND*, respectively,
// instead of ATOM and HWND, so that the actual storage can exist as a local
// variable or a member variable, and the scoper can be responsible for