summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-30 16:08:39 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-30 16:08:39 +0000
commite7b9ab2e29796ee7d8c9e6124917487d84749300 (patch)
tree55d2791989ccc9eaeccf5b29059906016837163e
parent2fb310fb27b2cf2bdd0efe39245f3ed1b7f8f6b8 (diff)
downloadchromium_src-e7b9ab2e29796ee7d8c9e6124917487d84749300.zip
chromium_src-e7b9ab2e29796ee7d8c9e6124917487d84749300.tar.gz
chromium_src-e7b9ab2e29796ee7d8c9e6124917487d84749300.tar.bz2
Generate crash dumps when a hung PPAPI plugin is force terminated.
Reland of 134443 with Auro build change. TEST=none BUG=123021 Review URL: https://chromiumcodereview.appspot.com/10272007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134537 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/hang_monitor/hang_crash_dump_win.cc45
-rw-r--r--chrome/browser/hang_monitor/hang_crash_dump_win.h14
-rw-r--r--chrome/browser/hang_monitor/hung_window_detector.cc44
-rw-r--r--chrome/browser/ui/hung_plugin_tab_helper.cc12
-rw-r--r--chrome/chrome_browser.gypi7
5 files changed, 81 insertions, 41 deletions
diff --git a/chrome/browser/hang_monitor/hang_crash_dump_win.cc b/chrome/browser/hang_monitor/hang_crash_dump_win.cc
new file mode 100644
index 0000000..ce02d81
--- /dev/null
+++ b/chrome/browser/hang_monitor/hang_crash_dump_win.cc
@@ -0,0 +1,45 @@
+// 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/hang_crash_dump_win.h"
+
+#include "chrome/common/chrome_constants.h"
+#include "content/public/common/result_codes.h"
+
+namespace {
+
+// 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;
+}
+
+// How long do we wait for the terminated thread or process to die (in ms)
+static const int kTerminateTimeoutMS = 2000;
+
+// How long do we wait for the crash to be generated (in ms).
+static const int kGenerateDumpTimeoutMS = 10000;
+
+} // namespace
+
+void CrashDumpAndTerminateHungChildProcess(HANDLE hprocess) {
+ // 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(hprocess, NULL, 0,
+ &HungPluginDumpAndExit, 0, 0, NULL);
+ if (remote_thread) {
+ WaitForSingleObject(remote_thread, kGenerateDumpTimeoutMS);
+ CloseHandle(remote_thread);
+ }
+
+ TerminateProcess(hprocess, content::RESULT_CODE_HUNG);
+ WaitForSingleObject(hprocess, kTerminateTimeoutMS);
+}
diff --git a/chrome/browser/hang_monitor/hang_crash_dump_win.h b/chrome/browser/hang_monitor/hang_crash_dump_win.h
new file mode 100644
index 0000000..d3b6629
--- /dev/null
+++ b/chrome/browser/hang_monitor/hang_crash_dump_win.h
@@ -0,0 +1,14 @@
+// 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.
+
+#ifndef CHROME_BROWSER_HANG_MONITOR_HANG_CRASH_DUMP_WIN_H_
+#define CHROME_BROWSER_HANG_MONITOR_HANG_CRASH_DUMP_WIN_H_
+
+#include <windows.h>
+
+// Causes the given child process to generate a crash dump and terminates the
+// process.
+void CrashDumpAndTerminateHungChildProcess(HANDLE hprocess);
+
+#endif // CHROME_BROWSER_HANG_MONITOR_HANG_CRASH_DUMP_WIN_H_
diff --git a/chrome/browser/hang_monitor/hung_window_detector.cc b/chrome/browser/hang_monitor/hung_window_detector.cc
index 3b6ad9b..d69ec68 100644
--- a/chrome/browser/hang_monitor/hung_window_detector.cc
+++ b/chrome/browser/hang_monitor/hung_window_detector.cc
@@ -3,41 +3,24 @@
// 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>
#include "base/logging.h"
+#include "chrome/browser/hang_monitor/hang_crash_dump_win.h"
#include "content/public/common/result_codes.h"
+namespace {
+
// 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;
+
+} // namespace
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),
@@ -178,23 +161,10 @@ 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);
+ CrashDumpAndTerminateHungChildProcess(child_process);
child_process.Close();
break;
}
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc
index 0b748dd..a16e4f7 100644
--- a/chrome/browser/ui/hung_plugin_tab_helper.cc
+++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/process_util.h"
+#include "build/build_config.h"
#include "chrome/browser/infobars/infobar_tab_helper.h"
#include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
@@ -21,6 +22,10 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
+#if defined(OS_WIN)
+#include "chrome/browser/hang_monitor/hang_crash_dump_win.h"
+#endif
+
namespace {
// Delay in seconds before re-showing the hung plugin message. This will be
@@ -40,10 +45,11 @@ void KillPluginOnIOThread(int child_id) {
while (!iter.Done()) {
const content::ChildProcessData& data = iter.GetData();
if (data.id == child_id) {
- // TODO(brettw) bug 123021: it might be nice to do some stuff to capture
- // a stack. The NPAPI Windows hang monitor does some cool stuff in
- // hung_window_detector.cc.
+#if defined(OS_WIN)
+ CrashDumpAndTerminateHungChildProcess(data.handle);
+#else
base::KillProcess(data.handle, content::RESULT_CODE_HUNG, false);
+#endif
break;
}
++iter;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 792a2e0..4e40945 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1063,6 +1063,8 @@
'browser/gpu_blacklist.h',
'browser/gpu_util.cc',
'browser/gpu_util.h',
+ 'browser/hang_monitor/hang_crash_dump_win.cc',
+ 'browser/hang_monitor/hang_crash_dump_win.h',
'browser/hang_monitor/hung_plugin_action.cc',
'browser/hang_monitor/hung_plugin_action.h',
'browser/hang_monitor/hung_window_detector.cc',
@@ -4261,7 +4263,10 @@
['exclude', '^browser/first_run/try_chrome_dialog_view.h'],
['exclude', '^browser/google/google_update.cc'],
['exclude', '^browser/google/google_update.h'],
- ['exclude', '^browser/hang_monitor/'],
+ ['exclude', '^browser/hang_monitor/hung_plugin_action.cc'],
+ ['exclude', '^browser/hang_monitor/hung_plugin_action.h'],
+ ['exclude', '^browser/hang_monitor/hung_window_detector.cc'],
+ ['exclude', '^browser/hang_monitor/hung_window_detector.h'],
['exclude', '^browser/renderer_host/render_widget_host_view_views*'],
['exclude', '^browser/tab_contents/web_drag_bookmark_handler_win.cc'],
['exclude', '^browser/tab_contents/web_drag_bookmark_handler_win.h'],