| Index: src/client/windows/unittests/exception_handler_test.cc
|
| ===================================================================
|
| --- src/client/windows/unittests/exception_handler_test.cc (revision 596)
|
| +++ src/client/windows/unittests/exception_handler_test.cc (working copy)
|
| @@ -60,7 +60,8 @@
|
| // Deletes temporary files.
|
| virtual void TearDown();
|
|
|
| - void DoCrash();
|
| + void DoCrashInvalidParameter();
|
| + void DoCrashPureVirtualCall();
|
|
|
| // Utility function to test for a path's existence.
|
| static BOOL DoesPathExist(const TCHAR *path_name);
|
| @@ -127,7 +128,7 @@
|
| full_dump_file = dump_file.substr(0, dump_file.length() - 4) + L"-full.dmp";
|
| }
|
|
|
| -void ExceptionHandlerTest::DoCrash() {
|
| +void ExceptionHandlerTest::DoCrashInvalidParameter() {
|
| google_breakpad::ExceptionHandler *exc =
|
| new google_breakpad::ExceptionHandler(
|
| temp_path_, NULL, NULL, NULL,
|
| @@ -144,6 +145,43 @@
|
| printf(NULL);
|
| }
|
|
|
| +
|
| +struct PureVirtualCallBase {
|
| + PureVirtualCallBase() {
|
| + // We have to reinterpret so the linker doesn't get confused because the
|
| + // method isn't defined.
|
| + reinterpret_cast<PureVirtualCallBase*>(this)->PureFunction();
|
| + }
|
| + virtual ~PureVirtualCallBase() {}
|
| + virtual void PureFunction() const = 0;
|
| +};
|
| +struct PureVirtualCall : public PureVirtualCallBase {
|
| + PureVirtualCall() { PureFunction(); }
|
| + virtual void PureFunction() const {}
|
| +};
|
| +
|
| +void ExceptionHandlerTest::DoCrashPureVirtualCall() {
|
| + google_breakpad::ExceptionHandler *exc =
|
| + new google_breakpad::ExceptionHandler(
|
| + temp_path_, NULL, NULL, NULL,
|
| + google_breakpad::ExceptionHandler::HANDLER_PURECALL,
|
| + kFullDumpType, kPipeName, NULL);
|
| +
|
| + // Disable the message box for assertions
|
| + _CrtSetReportMode(_CRT_ASSERT, 0);
|
| +
|
| + // Although this is executing in the child process of the death test,
|
| + // if it's not true we'll still get an error rather than the crash
|
| + // being expected.
|
| + ASSERT_TRUE(exc->IsOutOfProcess());
|
| +
|
| + // Create a new frame to ensure PureVirtualCall is not optimized to some
|
| + // other line in this function.
|
| + {
|
| + PureVirtualCall instance;
|
| + }
|
| +}
|
| +
|
| // This test validates that the minidump is written correctly.
|
| TEST_F(ExceptionHandlerTest, InvalidParameterMiniDumpTest) {
|
| ASSERT_TRUE(DoesPathExist(temp_path_));
|
| @@ -161,7 +199,7 @@
|
| // child process, the server registration will fail due to the named pipe
|
| // being the same.
|
| EXPECT_TRUE(server.Start());
|
| - EXPECT_EXIT(this->DoCrash(), ::testing::ExitedWithCode(0), "");
|
| + EXPECT_EXIT(DoCrashInvalidParameter(), ::testing::ExitedWithCode(0), "");
|
| ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty());
|
| ASSERT_TRUE(DoesPathExist(dump_file.c_str()));
|
|
|
| @@ -213,4 +251,75 @@
|
| EXPECT_FALSE(mini.HasStream(TokenStream));
|
| EXPECT_FALSE(full.HasStream(TokenStream));
|
| }
|
| +
|
| +
|
| +// This test validates that the minidump is written correctly.
|
| +TEST_F(ExceptionHandlerTest, PureVirtualCallMiniDumpTest) {
|
| + ASSERT_TRUE(DoesPathExist(temp_path_));
|
| +
|
| + // Call with a bad argument
|
| + ASSERT_TRUE(DoesPathExist(temp_path_));
|
| + std::wstring dump_path(temp_path_);
|
| + google_breakpad::CrashGenerationServer server(
|
| + kPipeName, NULL, NULL, NULL, ClientDumpCallback, NULL, NULL, NULL, true,
|
| + &dump_path);
|
| +
|
| + ASSERT_TRUE(dump_file.empty() && full_dump_file.empty());
|
| +
|
| + // This HAS to be EXPECT_, because when this test case is executed in the
|
| + // child process, the server registration will fail due to the named pipe
|
| + // being the same.
|
| + EXPECT_TRUE(server.Start());
|
| + EXPECT_EXIT(DoCrashPureVirtualCall(), ::testing::ExitedWithCode(0), "");
|
| + ASSERT_TRUE(!dump_file.empty() && !full_dump_file.empty());
|
| + ASSERT_TRUE(DoesPathExist(dump_file.c_str()));
|
| +
|
| + // Verify the dump for infos.
|
| + DumpAnalysis mini(dump_file);
|
| + DumpAnalysis full(full_dump_file);
|
| +
|
| + // The dump should have all of these streams.
|
| + EXPECT_TRUE(mini.HasStream(ThreadListStream));
|
| + EXPECT_TRUE(full.HasStream(ThreadListStream));
|
| + EXPECT_TRUE(mini.HasStream(ModuleListStream));
|
| + EXPECT_TRUE(full.HasStream(ModuleListStream));
|
| + EXPECT_TRUE(mini.HasStream(ExceptionStream));
|
| + EXPECT_TRUE(full.HasStream(ExceptionStream));
|
| + EXPECT_TRUE(mini.HasStream(SystemInfoStream));
|
| + EXPECT_TRUE(full.HasStream(SystemInfoStream));
|
| + EXPECT_TRUE(mini.HasStream(MiscInfoStream));
|
| + EXPECT_TRUE(full.HasStream(MiscInfoStream));
|
| + EXPECT_TRUE(mini.HasStream(HandleDataStream));
|
| + EXPECT_TRUE(full.HasStream(HandleDataStream));
|
| +
|
| + // We expect PEB and TEBs in this dump.
|
| + EXPECT_TRUE(mini.HasTebs() || full.HasTebs());
|
| + EXPECT_TRUE(mini.HasPeb() || full.HasPeb());
|
| +
|
| + // Minidump should have a memory listing, but no 64-bit memory.
|
| + EXPECT_TRUE(mini.HasStream(MemoryListStream));
|
| + EXPECT_FALSE(mini.HasStream(Memory64ListStream));
|
| +
|
| + EXPECT_FALSE(full.HasStream(MemoryListStream));
|
| + EXPECT_TRUE(full.HasStream(Memory64ListStream));
|
| +
|
| + // This is the only place we don't use OR because we want both not
|
| + // to have the streams.
|
| + EXPECT_FALSE(mini.HasStream(ThreadExListStream));
|
| + EXPECT_FALSE(full.HasStream(ThreadExListStream));
|
| + EXPECT_FALSE(mini.HasStream(CommentStreamA));
|
| + EXPECT_FALSE(full.HasStream(CommentStreamA));
|
| + EXPECT_FALSE(mini.HasStream(CommentStreamW));
|
| + EXPECT_FALSE(full.HasStream(CommentStreamW));
|
| + EXPECT_FALSE(mini.HasStream(FunctionTableStream));
|
| + EXPECT_FALSE(full.HasStream(FunctionTableStream));
|
| + EXPECT_FALSE(mini.HasStream(MemoryInfoListStream));
|
| + EXPECT_FALSE(full.HasStream(MemoryInfoListStream));
|
| + EXPECT_FALSE(mini.HasStream(ThreadInfoListStream));
|
| + EXPECT_FALSE(full.HasStream(ThreadInfoListStream));
|
| + EXPECT_FALSE(mini.HasStream(HandleOperationListStream));
|
| + EXPECT_FALSE(full.HasStream(HandleOperationListStream));
|
| + EXPECT_FALSE(mini.HasStream(TokenStream));
|
| + EXPECT_FALSE(full.HasStream(TokenStream));
|
| }
|
| +}
|
|
|