Home | History | Annotate | Download | only in hang_monitor
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/hang_monitor/hang_crash_dump_win.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/common/chrome_constants.h"
      9 #include "content/public/common/result_codes.h"
     10 
     11 namespace {
     12 
     13 // How long do we wait for the terminated thread or process to die (in ms)
     14 static const int kTerminateTimeoutMS = 2000;
     15 
     16 // How long do we wait for the crash to be generated (in ms).
     17 static const int kGenerateDumpTimeoutMS = 10000;
     18 
     19 }  // namespace
     20 
     21 void CrashDumpAndTerminateHungChildProcess(HANDLE hprocess) {
     22   // Before terminating the process we try collecting a dump. Which
     23   // a transient thread in the child process will do for us.
     24   typedef HANDLE (__cdecl *DumpFunction)(HANDLE);
     25   static DumpFunction request_dump = NULL;
     26   if (!request_dump) {
     27     request_dump = reinterpret_cast<DumpFunction>(GetProcAddress(
     28         GetModuleHandle(chrome::kBrowserProcessExecutableName),
     29             "InjectDumpProcessWithoutCrash"));
     30     DCHECK(request_dump) << "Failed loading DumpProcessWithoutCrash: error " <<
     31         GetLastError();
     32   }
     33 
     34   if (request_dump) {
     35     HANDLE remote_thread = request_dump(hprocess);
     36     DCHECK(remote_thread) << "Failed creating remote thread: error " <<
     37         GetLastError();
     38     if (remote_thread) {
     39       WaitForSingleObject(remote_thread, kGenerateDumpTimeoutMS);
     40       CloseHandle(remote_thread);
     41     }
     42   }
     43 
     44   TerminateProcess(hprocess, content::RESULT_CODE_HUNG);
     45   WaitForSingleObject(hprocess, kTerminateTimeoutMS);
     46 }
     47 
     48 void CrashDumpForHangDebugging(HANDLE hprocess) {
     49   if (hprocess == GetCurrentProcess()) {
     50     typedef void (__cdecl *DumpFunction)();
     51     DumpFunction request_dump = reinterpret_cast<DumpFunction>(GetProcAddress(
     52         GetModuleHandle(chrome::kBrowserProcessExecutableName),
     53         "DumpProcessWithoutCrash"));
     54     DCHECK(request_dump) << "Failed loading DumpProcessWithoutCrash: error " <<
     55         GetLastError();
     56     if (request_dump)
     57       request_dump();
     58   } else {
     59     typedef HANDLE (__cdecl *DumpFunction)(HANDLE);
     60     DumpFunction request_dump = reinterpret_cast<DumpFunction>(GetProcAddress(
     61         GetModuleHandle(chrome::kBrowserProcessExecutableName),
     62         "InjectDumpForHangDebugging"));
     63     DCHECK(request_dump) << "Failed loading InjectDumpForHangDebugging: error "
     64                          << GetLastError();
     65     if (request_dump) {
     66       HANDLE remote_thread = request_dump(hprocess);
     67       DCHECK(remote_thread) << "Failed creating remote thread: error " <<
     68           GetLastError();
     69       if (remote_thread) {
     70         WaitForSingleObject(remote_thread, kGenerateDumpTimeoutMS);
     71         CloseHandle(remote_thread);
     72       }
     73     }
     74   }
     75 }
     76