Allow CrashGenerationClient to request that a dump of the parent process be written.

A=Jim Mathies <jmathies@mozilla.com> R=ted at https://bugzilla.mozilla.org/show_bug.cgi?id=679238

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@883 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek 2011-11-11 19:05:51 +00:00
parent a8d599dc00
commit 06cede988b
13 changed files with 208 additions and 4 deletions

View file

@ -119,7 +119,8 @@ CrashGenerationServer::CrashGenerationServer(
shutting_down_(false),
overlapped_(),
client_info_(NULL),
cleanup_item_count_(0) {
cleanup_item_count_(0),
preferred_parent_thread_id_(0) {
InitializeCriticalSection(&clients_sync_);
if (dump_path) {
@ -600,6 +601,9 @@ bool CrashGenerationServer::PrepareReply(const ClientInfo& client_info,
CloseHandle(reply->server_alive_handle);
}
if (reply->parent_dump_request_handle) {
CloseHandle(reply->parent_dump_request_handle);
}
return false;
}
@ -626,6 +630,16 @@ bool CrashGenerationServer::CreateClientHandles(const ClientInfo& client_info,
return false;
}
if (!DuplicateHandle(current_process,
client_info.parent_dump_requested_handle(),
client_info.process_handle(),
&reply->parent_dump_request_handle,
kDumpRequestEventAccess,
FALSE,
0)) {
return false;
}
if (!DuplicateHandle(current_process,
server_alive_handle_,
client_info.process_handle(),
@ -754,6 +768,20 @@ bool CrashGenerationServer::AddClient(ClientInfo* client_info) {
client_info->set_process_exit_wait_handle(process_wait_handle);
// OnParentDumpRequest will be called if the client requests
// a server side minidump be generated.
HANDLE parent_request_wait_handle = NULL;
if (!RegisterWaitForSingleObject(&parent_request_wait_handle,
client_info->parent_dump_requested_handle(),
OnParentDumpRequest,
client_info,
INFINITE,
kDumpRequestThreadFlags)) {
return false;
}
client_info->set_parent_dump_request_wait_handle(parent_request_wait_handle);
// New scope to hold the lock for the shortest time.
{
AutoCriticalSection lock(&clients_sync_);
@ -785,6 +813,20 @@ void CALLBACK CrashGenerationServer::OnDumpRequest(void* context, BOOLEAN) {
ResetEvent(client_info->dump_requested_handle());
}
// static
void CALLBACK CrashGenerationServer::OnParentDumpRequest(void* context, BOOLEAN) {
assert(context);
ClientInfo* client_info = reinterpret_cast<ClientInfo*>(context);
client_info->PopulateCustomInfo();
CrashGenerationServer* crash_server = client_info->crash_server();
assert(crash_server);
crash_server->HandleParentDumpRequest(*client_info);
ResetEvent(client_info->parent_dump_requested_handle());
}
// static
void CALLBACK CrashGenerationServer::OnClientEnd(void* context, BOOLEAN) {
assert(context);
@ -843,7 +885,34 @@ void CrashGenerationServer::HandleDumpRequest(const ClientInfo& client_info) {
if (dump_callback_) {
std::wstring* ptr_dump_path = (dump_path == L"") ? NULL : &dump_path;
dump_callback_(dump_context_, &client_info, ptr_dump_path);
dump_callback_(dump_context_, &client_info, DUMP_REQ_CHILD, ptr_dump_path);
}
SetEvent(client_info.dump_generated_handle());
}
void CrashGenerationServer::HandleParentDumpRequest(const ClientInfo& client_info) {
std::wstring dump_path;
if (generate_dumps_) {
DWORD preferred_thread_id = !preferred_parent_thread_id_ ?
GetCurrentThreadId() : preferred_parent_thread_id_;
bool success =
dump_generator_->WriteMinidump(GetCurrentProcess(),
GetCurrentProcessId(),
preferred_thread_id,
GetCurrentThreadId(),
NULL, // no exception
NULL, // no assert info
MiniDumpNormal,
true,
&dump_path);
if (!success)
return;
}
if (dump_callback_) {
std::wstring* ptr_dump_path = (dump_path == L"") ? NULL : &dump_path;
dump_callback_(dump_context_, &client_info, DUMP_REQ_PARENT, ptr_dump_path);
}
SetEvent(client_info.dump_generated_handle());