• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CrashDumpAndTerminateHungChildProcess(HANDLE hprocess)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 
CrashDumpForHangDebugging(HANDLE hprocess)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