summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc398
1 files changed, 0 insertions, 398 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc b/toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc
deleted file mode 100644
index 0164f4a29..000000000
--- a/toolkit/crashreporter/google-breakpad/src/client/mac/tests/crash_generation_server_test.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-// Copyright (c) 2010, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// crash_generation_server_test.cc
-// Unit tests for CrashGenerationServer
-
-#include <dirent.h>
-#include <glob.h>
-#include <stdint.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
-
-#include "breakpad_googletest_includes.h"
-#include "client/mac/crash_generation/client_info.h"
-#include "client/mac/crash_generation/crash_generation_client.h"
-#include "client/mac/crash_generation/crash_generation_server.h"
-#include "client/mac/handler/exception_handler.h"
-#include "client/mac/tests/spawn_child_process.h"
-#include "common/tests/auto_tempdir.h"
-#include "google_breakpad/processor/minidump.h"
-
-namespace google_breakpad {
-// This acts as the log sink for INFO logging from the processor
-// logging code. The logging output confuses XCode and makes it think
-// there are unit test failures. testlogging.h handles the overriding.
-std::ostringstream info_log;
-}
-
-namespace {
-using std::string;
-using google_breakpad::AutoTempDir;
-using google_breakpad::ClientInfo;
-using google_breakpad::CrashGenerationClient;
-using google_breakpad::CrashGenerationServer;
-using google_breakpad::ExceptionHandler;
-using google_breakpad::Minidump;
-using google_breakpad::MinidumpContext;
-using google_breakpad::MinidumpException;
-using google_breakpad::MinidumpModule;
-using google_breakpad::MinidumpModuleList;
-using google_breakpad::MinidumpSystemInfo;
-using google_breakpad::MinidumpThread;
-using google_breakpad::MinidumpThreadList;
-using testing::Test;
-using namespace google_breakpad_test;
-
-class CrashGenerationServerTest : public Test {
-public:
- // The port name to receive messages on
- char mach_port_name[128];
- // Filename of the last dump that was generated
- string last_dump_name;
- // PID of the child process
- pid_t child_pid;
- // A temp dir
- AutoTempDir temp_dir;
- // Counter just to ensure that we don't hit the same port again
- static int i;
- bool filter_callback_called;
-
- void SetUp() {
- sprintf(mach_port_name,
- "com.google.breakpad.ServerTest.%d.%d", getpid(),
- CrashGenerationServerTest::i++);
- child_pid = (pid_t)-1;
- filter_callback_called = false;
- }
-};
-int CrashGenerationServerTest::i = 0;
-
-// Test that starting and stopping a server works
-TEST_F(CrashGenerationServerTest, testStartStopServer) {
- CrashGenerationServer server(mach_port_name,
- NULL, // filter callback
- NULL, // filter context
- NULL, // dump callback
- NULL, // dump context
- NULL, // exit callback
- NULL, // exit context
- false, // generate dumps
- ""); // dump path
- ASSERT_TRUE(server.Start());
- ASSERT_TRUE(server.Stop());
-}
-
-// Test that requesting a dump via CrashGenerationClient works
-// Test without actually dumping
-TEST_F(CrashGenerationServerTest, testRequestDumpNoDump) {
- CrashGenerationServer server(mach_port_name,
- NULL, // filter callback
- NULL, // filter context
- NULL, // dump callback
- NULL, // dump context
- NULL, // exit callback
- NULL, // exit context
- false, // don't generate dumps
- temp_dir.path()); // dump path
- ASSERT_TRUE(server.Start());
-
- pid_t pid = fork();
- ASSERT_NE(-1, pid);
- if (pid == 0) {
- CrashGenerationClient client(mach_port_name);
- bool result = client.RequestDump();
- exit(result ? 0 : 1);
- }
-
- int ret;
- ASSERT_EQ(pid, waitpid(pid, &ret, 0));
- EXPECT_TRUE(WIFEXITED(ret));
- EXPECT_EQ(0, WEXITSTATUS(ret));
- EXPECT_TRUE(server.Stop());
- // check that no minidump was written
- string pattern = temp_dir.path() + "/*";
- glob_t dirContents;
- ret = glob(pattern.c_str(), GLOB_NOSORT, NULL, &dirContents);
- EXPECT_EQ(GLOB_NOMATCH, ret);
- if (ret != GLOB_NOMATCH)
- globfree(&dirContents);
-}
-
-void dumpCallback(void *context, const ClientInfo &client_info,
- const std::string &file_path) {
- if (context) {
- CrashGenerationServerTest* self =
- reinterpret_cast<CrashGenerationServerTest*>(context);
- if (!file_path.empty())
- self->last_dump_name = file_path;
- self->child_pid = client_info.pid();
- }
-}
-
-void *RequestDump(void *context) {
- CrashGenerationClient client((const char*)context);
- bool result = client.RequestDump();
- return (void*)(result ? 0 : 1);
-}
-
-// Test that actually writing a minidump works
-TEST_F(CrashGenerationServerTest, testRequestDump) {
- CrashGenerationServer server(mach_port_name,
- NULL, // filter callback
- NULL, // filter context
- dumpCallback, // dump callback
- this, // dump context
- NULL, // exit callback
- NULL, // exit context
- true, // generate dumps
- temp_dir.path()); // dump path
- ASSERT_TRUE(server.Start());
-
- pid_t pid = fork();
- ASSERT_NE(-1, pid);
- if (pid == 0) {
- // Have to spawn off a separate thread to request the dump,
- // because MinidumpGenerator assumes the handler thread is not
- // the only thread
- pthread_t thread;
- if (pthread_create(&thread, NULL, RequestDump, (void*)mach_port_name) != 0)
- exit(1);
- void* result;
- pthread_join(thread, &result);
- exit(reinterpret_cast<intptr_t>(result));
- }
-
- int ret;
- ASSERT_EQ(pid, waitpid(pid, &ret, 0));
- EXPECT_TRUE(WIFEXITED(ret));
- EXPECT_EQ(0, WEXITSTATUS(ret));
- EXPECT_TRUE(server.Stop());
- // check that minidump was written
- ASSERT_FALSE(last_dump_name.empty());
- struct stat st;
- EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
- EXPECT_LT(0, st.st_size);
- // check client's PID
- ASSERT_EQ(pid, child_pid);
-}
-
-static void Crasher() {
- int *a = (int*)0x42;
-
- fprintf(stdout, "Going to crash...\n");
- fprintf(stdout, "A = %d", *a);
-}
-
-// Test that crashing a child process with an OOP ExceptionHandler installed
-// results in a minidump being written by the CrashGenerationServer in
-// the parent.
-TEST_F(CrashGenerationServerTest, testChildProcessCrash) {
- CrashGenerationServer server(mach_port_name,
- NULL, // filter callback
- NULL, // filter context
- dumpCallback, // dump callback
- this, // dump context
- NULL, // exit callback
- NULL, // exit context
- true, // generate dumps
- temp_dir.path()); // dump path
- ASSERT_TRUE(server.Start());
-
- pid_t pid = fork();
- ASSERT_NE(-1, pid);
- if (pid == 0) {
- // Instantiate an OOP exception handler.
- ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name);
- Crasher();
- // not reached
- exit(0);
- }
-
- int ret;
- ASSERT_EQ(pid, waitpid(pid, &ret, 0));
- EXPECT_FALSE(WIFEXITED(ret));
- EXPECT_TRUE(server.Stop());
- // check that minidump was written
- ASSERT_FALSE(last_dump_name.empty());
- struct stat st;
- EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
- EXPECT_LT(0, st.st_size);
-
- // Read the minidump, sanity check some data.
- Minidump minidump(last_dump_name.c_str());
- ASSERT_TRUE(minidump.Read());
-
- MinidumpSystemInfo* system_info = minidump.GetSystemInfo();
- ASSERT_TRUE(system_info);
- const MDRawSystemInfo* raw_info = system_info->system_info();
- ASSERT_TRUE(raw_info);
- EXPECT_EQ(kNativeArchitecture, raw_info->processor_architecture);
-
- MinidumpThreadList* thread_list = minidump.GetThreadList();
- ASSERT_TRUE(thread_list);
- ASSERT_EQ((unsigned int)1, thread_list->thread_count());
-
- MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0);
- ASSERT_TRUE(main_thread);
- MinidumpContext* context = main_thread->GetContext();
- ASSERT_TRUE(context);
- EXPECT_EQ(kNativeContext, context->GetContextCPU());
-
- MinidumpModuleList* module_list = minidump.GetModuleList();
- ASSERT_TRUE(module_list);
- const MinidumpModule* main_module = module_list->GetMainModule();
- ASSERT_TRUE(main_module);
- EXPECT_EQ(GetExecutablePath(), main_module->code_file());
-}
-
-#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) && \
- (defined(__x86_64__) || defined(__i386__))
-// Test that crashing a child process of a different architecture
-// produces a valid minidump.
-TEST_F(CrashGenerationServerTest, testChildProcessCrashCrossArchitecture) {
- CrashGenerationServer server(mach_port_name,
- NULL, // filter callback
- NULL, // filter context
- dumpCallback, // dump callback
- this, // dump context
- NULL, // exit callback
- NULL, // exit context
- true, // generate dumps
- temp_dir.path()); // dump path
- ASSERT_TRUE(server.Start());
-
- // Spawn a child process
- string helper_path = GetHelperPath();
- const char* argv[] = {
- helper_path.c_str(),
- "crash",
- mach_port_name,
- NULL
- };
- pid_t pid = spawn_child_process(argv);
- ASSERT_NE(-1, pid);
-
- int ret;
- ASSERT_EQ(pid, waitpid(pid, &ret, 0));
- EXPECT_FALSE(WIFEXITED(ret));
- EXPECT_TRUE(server.Stop());
- // check that minidump was written
- ASSERT_FALSE(last_dump_name.empty());
- struct stat st;
- EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
- EXPECT_LT(0, st.st_size);
-
-const MDCPUArchitecture kExpectedArchitecture =
-#if defined(__x86_64__)
- MD_CPU_ARCHITECTURE_X86
-#elif defined(__i386__)
- MD_CPU_ARCHITECTURE_AMD64
-#endif
- ;
-const uint32_t kExpectedContext =
-#if defined(__i386__)
- MD_CONTEXT_AMD64
-#elif defined(__x86_64__)
- MD_CONTEXT_X86
-#endif
- ;
-
- // Read the minidump, sanity check some data.
- Minidump minidump(last_dump_name.c_str());
- ASSERT_TRUE(minidump.Read());
-
- MinidumpSystemInfo* system_info = minidump.GetSystemInfo();
- ASSERT_TRUE(system_info);
- const MDRawSystemInfo* raw_info = system_info->system_info();
- ASSERT_TRUE(raw_info);
- EXPECT_EQ(kExpectedArchitecture, raw_info->processor_architecture);
-
- MinidumpThreadList* thread_list = minidump.GetThreadList();
- ASSERT_TRUE(thread_list);
- ASSERT_EQ((unsigned int)1, thread_list->thread_count());
-
- MinidumpThread* main_thread = thread_list->GetThreadAtIndex(0);
- ASSERT_TRUE(main_thread);
- MinidumpContext* context = main_thread->GetContext();
- ASSERT_TRUE(context);
- EXPECT_EQ(kExpectedContext, context->GetContextCPU());
-
- MinidumpModuleList* module_list = minidump.GetModuleList();
- ASSERT_TRUE(module_list);
- const MinidumpModule* main_module = module_list->GetMainModule();
- ASSERT_TRUE(main_module);
- EXPECT_EQ(helper_path, main_module->code_file());
-}
-#endif
-
-bool filter_callback(void* context) {
- CrashGenerationServerTest* self =
- reinterpret_cast<CrashGenerationServerTest*>(context);
- self->filter_callback_called = true;
- // veto dump generation
- return false;
-}
-
-// Test that a filter callback can veto minidump writing.
-TEST_F(CrashGenerationServerTest, testFilter) {
- CrashGenerationServer server(mach_port_name,
- filter_callback, // filter callback
- this, // filter context
- dumpCallback, // dump callback
- this, // dump context
- NULL, // exit callback
- NULL, // exit context
- true, // generate dumps
- temp_dir.path()); // dump path
- ASSERT_TRUE(server.Start());
-
- pid_t pid = fork();
- ASSERT_NE(-1, pid);
- if (pid == 0) {
- // Instantiate an OOP exception handler.
- ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name);
- Crasher();
- // not reached
- exit(0);
- }
-
- int ret;
- ASSERT_EQ(pid, waitpid(pid, &ret, 0));
- EXPECT_FALSE(WIFEXITED(ret));
- EXPECT_TRUE(server.Stop());
-
- // check that no minidump was written
- EXPECT_TRUE(last_dump_name.empty());
- EXPECT_TRUE(filter_callback_called);
-}
-
-} // namespace