| Index: chrome/browser/hang_monitor/hung_window_detector.cc
|
| ===================================================================
|
| --- chrome/browser/hang_monitor/hung_window_detector.cc (revision 134453)
|
| +++ chrome/browser/hang_monitor/hung_window_detector.cc (working copy)
|
| @@ -3,24 +3,41 @@
|
| // 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),
|
| @@ -161,10 +178,23 @@
|
| 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.
|
| - CrashDumpAndTerminateHungChildProcess(child_process);
|
| + 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();
|
| break;
|
| }
|
|
|