diff options
author | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2012-07-20 12:24:25 +0000 |
---|---|---|
committer | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2012-07-20 12:24:25 +0000 |
commit | b6b4451142d871d6b9d9162e465dff5d4511cef9 (patch) | |
tree | b4f59f3874bd567a188969bb81718deee99eca93 /src/client | |
parent | Allow adding extra memory regions to minidump on linux/windows (diff) | |
download | breakpad-b6b4451142d871d6b9d9162e465dff5d4511cef9.tar.xz |
Add a filter callback to CrashGenerationServer on mac
A=Rafael Ávila de Espíndola <respindola@mozilla.com> R=ted at https://bugzilla.mozilla.org/show_bug.cgi?id=732173
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@990 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client')
3 files changed, 76 insertions, 10 deletions
diff --git a/src/client/mac/crash_generation/crash_generation_server.cc b/src/client/mac/crash_generation/crash_generation_server.cc index 44548ef0..b3eb403f 100644 --- a/src/client/mac/crash_generation/crash_generation_server.cc +++ b/src/client/mac/crash_generation/crash_generation_server.cc @@ -37,6 +37,8 @@ namespace google_breakpad { CrashGenerationServer::CrashGenerationServer( const char *mach_port_name, + FilterCallback filter, + void *filter_context, OnClientDumpRequestCallback dump_callback, void *dump_context, OnClientExitingCallback exit_callback, @@ -44,6 +46,8 @@ CrashGenerationServer::CrashGenerationServer( bool generate_dumps, const std::string &dump_path) : dump_callback_(dump_callback), + filter_(filter), + filter_context_(filter_context), dump_context_(dump_context), exit_callback_(exit_callback), exit_context_(exit_context), @@ -110,7 +114,7 @@ bool CrashGenerationServer::WaitForOneMessage() { bool result; std::string dump_path; - if (generate_dumps_) { + if (generate_dumps_ && (!filter_ || filter_(filter_context_))) { ScopedTaskSuspend suspend(remote_task); MinidumpGenerator generator(remote_task, handler_thread); diff --git a/src/client/mac/crash_generation/crash_generation_server.h b/src/client/mac/crash_generation/crash_generation_server.h index 6e6cb44d..85bd5b5e 100644 --- a/src/client/mac/crash_generation/crash_generation_server.h +++ b/src/client/mac/crash_generation/crash_generation_server.h @@ -65,10 +65,14 @@ class CrashGenerationServer { typedef void (*OnClientExitingCallback)(void *context, const ClientInfo &client_info); + // If a FilterCallback returns false, the dump will not be written. + typedef bool (*FilterCallback)(void *context); // Create an instance with the given parameters. // // mach_port_name: Named server port to listen on. + // filter: Callback for a client to cancel writing a dump. + // filter_context: Context for the filter callback. // dump_callback: Callback for a client crash dump request. // dump_context: Context for client crash dump request callback. // exit_callback: Callback for client process exit. @@ -80,6 +84,8 @@ class CrashGenerationServer { // dump_path: Path for generating dumps; required only if true is // passed for generateDumps parameter; NULL can be passed otherwise. CrashGenerationServer(const char *mach_port_name, + FilterCallback filter, + void *filter_context, OnClientDumpRequestCallback dump_callback, void *dump_context, OnClientExitingCallback exit_callback, @@ -109,6 +115,9 @@ class CrashGenerationServer { // if a quit message was received or if an error occurred. bool WaitForOneMessage(); + FilterCallback filter_; + void *filter_context_; + OnClientDumpRequestCallback dump_callback_; void *dump_context_; diff --git a/src/client/mac/tests/crash_generation_server_test.cc b/src/client/mac/tests/crash_generation_server_test.cc index f71624df..ff8ff78d 100644 --- a/src/client/mac/tests/crash_generation_server_test.cc +++ b/src/client/mac/tests/crash_generation_server_test.cc @@ -84,12 +84,14 @@ public: 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++); + "com.google.breakpad.ServerTest.%d.%d", getpid(), + CrashGenerationServerTest::i++); child_pid = (pid_t)-1; + filter_callback_called = false; } }; int CrashGenerationServerTest::i = 0; @@ -97,12 +99,14 @@ int CrashGenerationServerTest::i = 0; // Test that starting and stopping a server works TEST_F(CrashGenerationServerTest, testStartStopServer) { CrashGenerationServer server(mach_port_name, - NULL, // dump callback - NULL, // dump context - NULL, // exit callback - NULL, // exit context - false, // generate dumps - ""); // dump path + 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()); } @@ -111,6 +115,8 @@ TEST_F(CrashGenerationServerTest, testStartStopServer) { // 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 @@ -142,7 +148,7 @@ TEST_F(CrashGenerationServerTest, testRequestDumpNoDump) { } void dumpCallback(void *context, const ClientInfo &client_info, - const std::string &file_path) { + const std::string &file_path) { if (context) { CrashGenerationServerTest* self = reinterpret_cast<CrashGenerationServerTest*>(context); @@ -161,6 +167,8 @@ void *RequestDump(void *context) { // 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 @@ -209,6 +217,8 @@ static void Crasher() { // 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 @@ -270,6 +280,8 @@ TEST_F(CrashGenerationServerTest, testChildProcessCrash) { // 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 @@ -342,4 +354,45 @@ const u_int32_t kExpectedContext = } #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 |