Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Unified Diff: snapshot/win/exception_snapshot_win_test.cc

Issue 1356383002: win: Implement CRASHPAD_SIMULATE_CRASH() (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: fixes Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « snapshot/win/crashpad_snapshot_test_dump_without_crashing.cc ('k') | util/win/exception_handler_server.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: snapshot/win/exception_snapshot_win_test.cc
diff --git a/snapshot/win/exception_snapshot_win_test.cc b/snapshot/win/exception_snapshot_win_test.cc
index c074eb5499ab6f0319484dd7174e7972faccadc5..4108a575978f92dc10f2b325b64fb0a078aef71b 100644
--- a/snapshot/win/exception_snapshot_win_test.cc
+++ b/snapshot/win/exception_snapshot_win_test.cc
@@ -36,27 +36,51 @@ namespace crashpad {
namespace test {
namespace {
-HANDLE DuplicateEvent(HANDLE process, HANDLE event) {
- HANDLE handle;
- if (DuplicateHandle(GetCurrentProcess(),
- event,
- process,
- &handle,
- SYNCHRONIZE | EVENT_MODIFY_STATE,
- false,
- 0)) {
- return handle;
+// Runs the ExceptionHandlerServer on a background thread.
+class RunServerThread : public Thread {
+ public:
+ // Instantiates a thread which will invoke server->Run(delegate, pipe_name);
+ RunServerThread(ExceptionHandlerServer* server,
+ ExceptionHandlerServer::Delegate* delegate,
+ const std::string& pipe_name)
+ : server_(server), delegate_(delegate), pipe_name_(pipe_name) {}
+ ~RunServerThread() override {}
+
+ private:
+ // Thread:
+ void ThreadMain() override { server_->Run(delegate_, pipe_name_); }
+
+ ExceptionHandlerServer* server_;
+ ExceptionHandlerServer::Delegate* delegate_;
+ std::string pipe_name_;
+
+ DISALLOW_COPY_AND_ASSIGN(RunServerThread);
+};
+
+// During destruction, ensures that the server is stopped and the background
+// thread joined.
+class ScopedStopServerAndJoinThread {
+ public:
+ ScopedStopServerAndJoinThread(ExceptionHandlerServer* server, Thread* thread)
+ : server_(server), thread_(thread) {}
+ ~ScopedStopServerAndJoinThread() {
+ server_->Stop();
+ thread_->Join();
}
- return nullptr;
-}
-class Delegate : public ExceptionHandlerServer::Delegate {
+ private:
+ ExceptionHandlerServer* server_;
+ Thread* thread_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedStopServerAndJoinThread);
+};
+
+class CrashingDelegate : public ExceptionHandlerServer::Delegate {
public:
- Delegate(HANDLE server_ready, HANDLE completed_test_event)
+ CrashingDelegate(HANDLE server_ready, HANDLE completed_test_event)
: server_ready_(server_ready),
completed_test_event_(completed_test_event),
break_near_(0) {}
- ~Delegate() override {}
+ ~CrashingDelegate() override {}
void set_break_near(WinVMAddress break_near) { break_near_ = break_near; }
@@ -76,7 +100,7 @@ class Delegate : public ExceptionHandlerServer::Delegate {
// Verify the exception happened at the expected location with a bit of
// slop space to allow for reading the current PC before the exception
- // happens. See CrashingChildProcess::Run().
+ // happens. See TestCrashingChild().
const uint64_t kAllowedOffset = 64;
EXPECT_GT(snapshot.Exception()->ExceptionAddress(), break_near_);
EXPECT_LT(snapshot.Exception()->ExceptionAddress(),
@@ -92,45 +116,7 @@ class Delegate : public ExceptionHandlerServer::Delegate {
HANDLE completed_test_event_; // weak
WinVMAddress break_near_;
- DISALLOW_COPY_AND_ASSIGN(Delegate);
-};
-
-// Runs the ExceptionHandlerServer on a background thread.
-class RunServerThread : public Thread {
- public:
- // Instantiates a thread which will invoke server->Run(delegate, pipe_name);
- RunServerThread(ExceptionHandlerServer* server,
- ExceptionHandlerServer::Delegate* delegate,
- const std::string& pipe_name)
- : server_(server), delegate_(delegate), pipe_name_(pipe_name) {}
- ~RunServerThread() override {}
-
- private:
- // Thread:
- void ThreadMain() override { server_->Run(delegate_, pipe_name_); }
-
- ExceptionHandlerServer* server_;
- ExceptionHandlerServer::Delegate* delegate_;
- std::string pipe_name_;
-
- DISALLOW_COPY_AND_ASSIGN(RunServerThread);
-};
-
-// During destruction, ensures that the server is stopped and the background
-// thread joined.
-class ScopedStopServerAndJoinThread {
- public:
- ScopedStopServerAndJoinThread(ExceptionHandlerServer* server, Thread* thread)
- : server_(server), thread_(thread) {}
- ~ScopedStopServerAndJoinThread() {
- server_->Stop();
- thread_->Join();
- }
-
- private:
- ExceptionHandlerServer* server_;
- Thread* thread_;
- DISALLOW_COPY_AND_ASSIGN(ScopedStopServerAndJoinThread);
+ DISALLOW_COPY_AND_ASSIGN(CrashingDelegate);
};
void TestCrashingChild(const base::string16& directory_modification) {
@@ -139,7 +125,7 @@ void TestCrashingChild(const base::string16& directory_modification) {
base::StringPrintf("%08x", GetCurrentProcessId());
ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr));
ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr));
- Delegate delegate(server_ready.get(), completed.get());
+ CrashingDelegate delegate(server_ready.get(), completed.get());
ExceptionHandlerServer exception_handler_server;
RunServerThread server_thread(
@@ -186,6 +172,104 @@ TEST(ExceptionSnapshotWinTest, ChildCrashWOW64) {
}
#endif // ARCH_CPU_64_BITS
+class SimulateDelegate : public ExceptionHandlerServer::Delegate {
+ public:
+ SimulateDelegate(HANDLE server_ready, HANDLE completed_test_event)
+ : server_ready_(server_ready),
+ completed_test_event_(completed_test_event),
+ dump_near_(0) {}
+ ~SimulateDelegate() override {}
+
+ void set_dump_near(WinVMAddress dump_near) { dump_near_ = dump_near; }
+
+ void ExceptionHandlerServerStarted() override { SetEvent(server_ready_); }
+
+ unsigned int ExceptionHandlerServerException(
+ HANDLE process,
+ WinVMAddress exception_information_address) override {
+ ScopedProcessSuspend suspend(process);
+ ProcessSnapshotWin snapshot;
+ snapshot.Initialize(process, ProcessSuspensionState::kSuspended);
+ snapshot.InitializeException(exception_information_address);
+ EXPECT_TRUE(snapshot.Exception());
+ EXPECT_EQ(0, snapshot.Exception()->Exception());
+ EXPECT_EQ(0, snapshot.Exception()->ExceptionAddress());
+
+ // Verify the dump was captured at the expected location with some slop
+ // space.
+ const uint64_t kAllowedOffset = 64;
+ EXPECT_GT(snapshot.Exception()->Context()->InstructionPointer(),
+ dump_near_);
+ EXPECT_LT(snapshot.Exception()->Context()->InstructionPointer(),
+ dump_near_ + kAllowedOffset);
+
+ SetEvent(completed_test_event_);
+
+ return 0;
+ }
+
+ private:
+ HANDLE server_ready_; // weak
+ HANDLE completed_test_event_; // weak
+ WinVMAddress dump_near_;
+
+ DISALLOW_COPY_AND_ASSIGN(SimulateDelegate);
+};
+
+void TestDumpWithoutCrashingChild(
+ const base::string16& directory_modification) {
+ // Set up the registration server on a background thread.
+ std::string pipe_name = "\\\\.\\pipe\\handler_test_pipe_" +
+ base::StringPrintf("%08x", GetCurrentProcessId());
+ ScopedKernelHANDLE server_ready(CreateEvent(nullptr, false, false, nullptr));
+ ScopedKernelHANDLE completed(CreateEvent(nullptr, false, false, nullptr));
+ SimulateDelegate delegate(server_ready.get(), completed.get());
+
+ ExceptionHandlerServer exception_handler_server;
+ RunServerThread server_thread(
+ &exception_handler_server, &delegate, pipe_name);
+ server_thread.Start();
+ ScopedStopServerAndJoinThread scoped_stop_server_and_join_thread(
+ &exception_handler_server, &server_thread);
+
+ WaitForSingleObject(server_ready.get(), INFINITE);
+
+ // Spawn a child process, passing it the pipe name to connect to.
+ base::FilePath test_executable = Paths::Executable();
+ std::wstring child_test_executable =
+ test_executable.DirName()
+ .Append(directory_modification)
+ .Append(test_executable.BaseName().RemoveFinalExtension().value() +
+ L"_dump_without_crashing.exe")
+ .value();
+ ChildLauncher child(child_test_executable, base::UTF8ToUTF16(pipe_name));
+ child.Start();
+
+ // The child tells us (approximately) where it will capture a dump.
+ WinVMAddress dump_near_address;
+ LoggingReadFile(child.stdout_read_handle(),
+ &dump_near_address,
+ sizeof(dump_near_address));
+ delegate.set_dump_near(dump_near_address);
+
+ // Wait for the child to crash and the exception information to be validated.
+ WaitForSingleObject(completed.get(), INFINITE);
+}
+
+TEST(SimulateCrash, ChildDumpWithoutCrashing) {
+ TestDumpWithoutCrashingChild(FILE_PATH_LITERAL("."));
+}
+
+#if defined(ARCH_CPU_64_BITS)
+TEST(SimulateCrash, ChildDumpWithoutCrashingWOW64) {
+#ifndef NDEBUG
+ TestDumpWithoutCrashingChild(FILE_PATH_LITERAL("..\\..\\out\\Debug"));
+#else
+ TestDumpWithoutCrashingChild(FILE_PATH_LITERAL("..\\..\\out\\Release"));
+#endif
+}
+#endif // ARCH_CPU_64_BITS
+
} // namespace
} // namespace test
} // namespace crashpad
« no previous file with comments | « snapshot/win/crashpad_snapshot_test_dump_without_crashing.cc ('k') | util/win/exception_handler_server.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698