Overview:
Implement out-of-process dump generation for Windows platform.
Details:
- Created a lib, crash_generation.lib, that implements the out-of-process dump generation protocol.
- The lib code is under client/windows/crash_generation folder and is organized in the following way:
- CrashGenerationServer class (crash_generation_server.h/.cc) implements the server side of
the protocol.
- CrashGenerationClient class (crash_generation_client.h/.cc) implements the client side of
the protocol.
- MinidumpGenerator class (minidump_generator.h/.cc) serves as an abstractino for generating
dump files using Windows APIs, coming up with new file names by creating GUIDs, etc.
- ProtocolMessage class (ipc_protocol.h) represents the message format between the client and server
for pipe IPC.
- Server allows one client at a time on the pipe in the current implementation.
- ReadMe.txt explains the state machine the server uses to serve clients.
- ExceptionHandler is modified and a new constructor is added that allows specifying the pipe name. If the
pipe name is NULL, the behavior is backward compatible - in-process dump generation is done as before. If
the pipe name is specified, out-of-process dump generation registration is attempted. If that fails, the
behavior is again backward compatible.
- If out-of-process registration succeeds, all write dump requests, direct or indirect, are directed to
crash server process that served the registration request. NOTE that the explicit dump requests made by
calling the static method of ExceptionHandler are not directed to theserver.
- client/windows/tests/crash_generation_app implements a simple Win32 GUI application to help test the
out-of-process dump generation client and server. Typical use of the app is to start one instance, click
Server --> Start and then start the other instance. The other instance will register with the first
instance automatically at start-up. Then the second instance can be used to request various typoes of
dump requests by using options under the Client menu.
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@244 4c0a9323-5329-0410-9bdc-e9ce6186880e
diff --git a/src/client/windows/handler/exception_handler.h b/src/client/windows/handler/exception_handler.h
index fc9af32..870025f 100644
--- a/src/client/windows/handler/exception_handler.h
+++ b/src/client/windows/handler/exception_handler.h
@@ -68,7 +68,9 @@
#include <string>
#include <vector>
+#include "client/windows/crash_generation/crash_generation_client.h"
#include "google_breakpad/common/minidump_format.h"
+#include "processor/scoped_ptr.h"
namespace google_breakpad {
@@ -88,8 +90,8 @@
// attempting to write a minidump. If a FilterCallback returns false, Breakpad
// will immediately report the exception as unhandled without writing a
// minidump, allowing another handler the opportunity to handle it.
- typedef bool (*FilterCallback)(void *context, EXCEPTION_POINTERS *exinfo,
- MDRawAssertionInfo *assertion);
+ typedef bool (*FilterCallback)(void* context, EXCEPTION_POINTERS* exinfo,
+ MDRawAssertionInfo* assertion);
// A callback function to run after the minidump has been written.
// minidump_id is a unique id for the dump, so the minidump
@@ -110,11 +112,16 @@
// should normally return the value of |succeeded|, or when they wish to
// not report an exception of handled, false. Callbacks will rarely want to
// return true directly (unless |succeeded| is true).
- typedef bool (*MinidumpCallback)(const wchar_t *dump_path,
- const wchar_t *minidump_id,
- void *context,
- EXCEPTION_POINTERS *exinfo,
- MDRawAssertionInfo *assertion,
+ //
+ // For out-of-process dump generation, dump path and minidump ID will always
+ // be NULL. In case of out-of-process dump generation, the dump path and
+ // minidump id are controlled by the server process and are not communicated
+ // back to the crashing process.
+ typedef bool (*MinidumpCallback)(const wchar_t* dump_path,
+ const wchar_t* minidump_id,
+ void* context,
+ EXCEPTION_POINTERS* exinfo,
+ MDRawAssertionInfo* assertion,
bool succeeded);
// HandlerType specifies which types of handlers should be installed, if
@@ -139,11 +146,25 @@
// minidump. Minidump files will be written to dump_path, and the optional
// callback is called after writing the dump file, as described above.
// handler_types specifies the types of handlers that should be installed.
- ExceptionHandler(const wstring &dump_path,
+ ExceptionHandler(const wstring& dump_path,
FilterCallback filter,
MinidumpCallback callback,
- void *callback_context,
+ void* callback_context,
int handler_types);
+
+ // Creates a new ExcetpionHandler instance that can attempt to perform
+ // out-of-process dump generation if pipe_name is not NULL. If pipe_name is
+ // NULL, or if out-of-process dump generation registration step fails,
+ // in-process dump generation will be used. This also allows specifying
+ // the dump type to generate.
+ ExceptionHandler(const wstring& dump_path,
+ FilterCallback filter,
+ MinidumpCallback callback,
+ void* callback_context,
+ int handler_types,
+ MINIDUMP_TYPE dump_type,
+ const wchar_t* pipe_name);
+
~ExceptionHandler();
// Get and set the minidump path.
@@ -160,12 +181,12 @@
// Writes a minidump immediately, with the user-supplied exception
// information.
- bool WriteMinidumpForException(EXCEPTION_POINTERS *exinfo);
+ bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);
// Convenience form of WriteMinidump which does not require an
// ExceptionHandler instance.
static bool WriteMinidump(const wstring &dump_path,
- MinidumpCallback callback, void *callback_context);
+ MinidumpCallback callback, void* callback_context);
// Get the thread ID of the thread requesting the dump (either the exception
// thread or any other thread that called WriteMinidump directly). This
@@ -179,9 +200,21 @@
handle_debug_exceptions_ = handle_debug_exceptions;
}
+ // Returns whether out-of-process dump generation is used or not.
+ bool IsOutOfProcess() const { return crash_generation_client_.get() != NULL; }
+
private:
friend class AutoExceptionHandler;
+ // Initializes the instance with given values.
+ void Initialize(const wstring& dump_path,
+ FilterCallback filter,
+ MinidumpCallback callback,
+ void* callback_context,
+ int handler_types,
+ MINIDUMP_TYPE dump_type,
+ const wchar_t* pipe_name);
+
// Function pointer type for MiniDumpWriteDump, which is looked up
// dynamically.
typedef BOOL (WINAPI *MiniDumpWriteDump_type)(
@@ -194,14 +227,14 @@
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
// Function pointer type for UuidCreate, which is looked up dynamically.
- typedef RPC_STATUS (RPC_ENTRY *UuidCreate_type)(UUID *Uuid);
+ typedef RPC_STATUS (RPC_ENTRY *UuidCreate_type)(UUID* Uuid);
// Runs the main loop for the exception handler thread.
- static DWORD WINAPI ExceptionHandlerThreadMain(void *lpParameter);
+ static DWORD WINAPI ExceptionHandlerThreadMain(void* lpParameter);
// Called on the exception thread when an unhandled exception occurs.
// Signals the exception handler thread to handle the exception.
- static LONG WINAPI HandleException(EXCEPTION_POINTERS *exinfo);
+ static LONG WINAPI HandleException(EXCEPTION_POINTERS* exinfo);
#if _MSC_VER >= 1400 // MSVC 2005/8
// This function will be called by some CRT functions when they detect
@@ -209,9 +242,9 @@
// the CRT may display an assertion dialog before calling this function,
// and the function will not be called unless the assertion dialog is
// dismissed by clicking "Ignore."
- static void HandleInvalidParameter(const wchar_t *expression,
- const wchar_t *function,
- const wchar_t *file,
+ static void HandleInvalidParameter(const wchar_t* expression,
+ const wchar_t* function,
+ const wchar_t* file,
unsigned int line,
uintptr_t reserved);
#endif // _MSC_VER >= 1400
@@ -229,8 +262,8 @@
// is NULL. If the dump is requested as a result of an assertion
// (such as an invalid parameter being passed to a CRT function),
// assertion contains data about the assertion, otherwise, it is NULL.
- bool WriteMinidumpOnHandlerThread(EXCEPTION_POINTERS *exinfo,
- MDRawAssertionInfo *assertion);
+ bool WriteMinidumpOnHandlerThread(EXCEPTION_POINTERS* exinfo,
+ MDRawAssertionInfo* assertion);
// This function does the actual writing of a minidump. It is called
// on the handler thread. requesting_thread_id is the ID of the thread
@@ -238,8 +271,8 @@
// an exception, exinfo contains exception information, otherwise,
// it is NULL.
bool WriteMinidumpWithException(DWORD requesting_thread_id,
- EXCEPTION_POINTERS *exinfo,
- MDRawAssertionInfo *assertion);
+ EXCEPTION_POINTERS* exinfo,
+ MDRawAssertionInfo* assertion);
// Generates a new ID and stores it in next_minidump_id_, and stores the
// path of the next minidump to be written in next_minidump_path_.
@@ -247,7 +280,9 @@
FilterCallback filter_;
MinidumpCallback callback_;
- void *callback_context_;
+ void* callback_context_;
+
+ scoped_ptr<CrashGenerationClient> crash_generation_client_;
// The directory in which a minidump will be written, set by the dump_path
// argument to the constructor, or set_dump_path.
@@ -266,12 +301,13 @@
// pointers are not owned by the ExceptionHandler object, but their lifetimes
// should be equivalent to the lifetimes of the associated wstring, provided
// that the wstrings are not altered.
- const wchar_t *dump_path_c_;
- const wchar_t *next_minidump_id_c_;
- const wchar_t *next_minidump_path_c_;
+ const wchar_t* dump_path_c_;
+ const wchar_t* next_minidump_id_c_;
+ const wchar_t* next_minidump_path_c_;
HMODULE dbghelp_module_;
MiniDumpWriteDump_type minidump_write_dump_;
+ MINIDUMP_TYPE dump_type_;
HMODULE rpcrt4_module_;
UuidCreate_type uuid_create_;
@@ -322,11 +358,11 @@
// The exception info passed to the exception handler on the exception
// thread, if an exception occurred. NULL for user-requested dumps.
- EXCEPTION_POINTERS *exception_info_;
+ EXCEPTION_POINTERS* exception_info_;
// If the handler is invoked due to an assertion, this will contain a
// pointer to the assertion information. It is NULL at other times.
- MDRawAssertionInfo *assertion_;
+ MDRawAssertionInfo* assertion_;
// The return value of the handler, passed from the handler thread back to
// the requesting thread.
@@ -342,7 +378,7 @@
// which ExceptionHandler object to route an exception to. When an
// ExceptionHandler is created with install_handler true, it will append
// itself to this list.
- static vector<ExceptionHandler *> *handler_stack_;
+ static vector<ExceptionHandler*>* handler_stack_;
// The index of the ExceptionHandler in handler_stack_ that will handle the
// next exception. Note that 0 means the last entry in handler_stack_, 1