diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-22 23:54:19 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-22 23:54:19 +0000 |
commit | d8b3c89acf572a7be1776e972af01a6bb183a477 (patch) | |
tree | 8b41a3d0c4ef804d2e01886f1f9755efa3b4972a /chrome/browser/hang_monitor | |
parent | 4b87bc2e3c13bd572a2b1b9a08ea2644120e6d6c (diff) | |
download | chromium_src-d8b3c89acf572a7be1776e972af01a6bb183a477.zip chromium_src-d8b3c89acf572a7be1776e972af01a6bb183a477.tar.gz chromium_src-d8b3c89acf572a7be1776e972af01a6bb183a477.tar.bz2 |
Generate crash dump when the user selects to kill hung plugin.
A remote thread is used to call DumpProcessWithoutCrash(), this should
give us a snapshot without disturbing the hung state.
BUG=119390
TEST=see bug
Review URL: https://chromiumcodereview.appspot.com/9812041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128339 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/hang_monitor')
-rw-r--r-- | chrome/browser/hang_monitor/hung_window_detector.cc | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/chrome/browser/hang_monitor/hung_window_detector.cc b/chrome/browser/hang_monitor/hung_window_detector.cc index a1c0050..3b6ad9b 100644 --- a/chrome/browser/hang_monitor/hung_window_detector.cc +++ b/chrome/browser/hang_monitor/hung_window_detector.cc @@ -1,8 +1,9 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/hang_monitor/hung_window_detector.h" +#include "chrome/common/chrome_constants.h" #include <windows.h> #include <atlbase.h> @@ -12,10 +13,31 @@ // How long do we wait for the terminated thread or process to die (in ms) static const int kTerminateTimeout = 2000; +// How long do we wait for the crash to be generated (in ms). +static const int kGenerateDumpTimeout = 10000; const wchar_t HungWindowDetector::kHungChildWindowTimeout[] = L"Chrome_HungChildWindowTimeout"; +namespace { + +typedef void (*DumpProcessWithoutCrashFn)(); +// This function will be called via an injected thread in the hung plugin +// process. calling DumpProcessWithoutCrash causes breakpad to capture a dump of +// the process. +DWORD WINAPI HungPluginDumpAndExit(void*) { + typedef void (__cdecl *DumpProcessFunction)(); + DumpProcessFunction request_dump = reinterpret_cast<DumpProcessFunction>( + ::GetProcAddress(::GetModuleHandle( + chrome::kBrowserProcessExecutableName), + "DumpProcessWithoutCrash")); + if (request_dump) + request_dump(); + return 0; +} + +} // namespace + HungWindowDetector::HungWindowDetector(HungWindowNotification* notification) : notification_(notification), top_level_window_(NULL), @@ -142,7 +164,7 @@ bool HungWindowDetector::CheckChildWindow(HWND child_window) { } case HungWindowNotification::HUNG_WINDOW_TERMINATE_PROCESS: { RemoveProp(child_window, kHungChildWindowTimeout); - CHandle child_process(OpenProcess(PROCESS_TERMINATE, + CHandle child_process(OpenProcess(PROCESS_ALL_ACCESS, FALSE, child_window_process_id)); @@ -156,6 +178,21 @@ bool HungWindowDetector::CheckChildWindow(HWND child_window) { if (process_id_check != child_window_process_id) { break; } + // Before terminating the process we try collecting a dump. Which + // a transient thread in the child process will do for us. + HANDLE remote_thread = + CreateRemoteThread(child_process, + NULL, + 0, + &HungPluginDumpAndExit, + 0, + 0, + NULL); + if (remote_thread) { + WaitForSingleObject(remote_thread, kGenerateDumpTimeout); + CloseHandle(remote_thread); + } + TerminateProcess(child_process, content::RESULT_CODE_HUNG); WaitForSingleObject(child_process, kTerminateTimeout); child_process.Close(); |